一、Spring基础 --- 基础内容(一) (咕P4)

一、Spring简介

1 来源

Struts与Hibernate可以做什么事?

xml 复制代码
	
	Struts:
			Mvc中控制层解决方案 
			可以进行请求数据自动封装、类型转换、文件上传、效验...
	
	Hibernate:
			持久层的解决方案; 
			可以做到,
					把对象保存到数据库, 
					从数据库中取出的是对象。
					

传统的开发模式、开发流程

xml 复制代码
	传统的开发模式:基于mvc模式进行项目开发
java 复制代码
	基于mvc的项目框架结构:
			Entity / dao / service / action

			// 1. 实体类
			class User{
			}
			//2. dao
			class  UserDao{
			   .. 访问db
			}			
			//3. service
			class  UserService{
			    UserDao userDao = new UserDao();
			}
			
			
			//4. action
			class  UserAction{
			    UserService userService = new UserService();
			
			    ..
			    拿到数据或结果
			}
			
			用户访问:
			/user.action ---->  Tomcat  (服务器创建Action、Service、dao

思考

java 复制代码
	思考:
	    1. 对象创建创建能否写死?
	    2. 对象创建细节
	        对象数量
	            action  多个   【维护成员变量】
	            service 一个   【不需要维护公共变量】
	            dao     一个   【不需要维护公共变量】
	        创建时间
	            action    访问时候创建
	            service   启动时候创建
	            dao       启动时候创建
	  
	    3. 对象的依赖关系
	        action 依赖 service
	        service依赖 dao

		=======================================================
		总结:
		    spring就是解决上面的问题的!
		简单来说,就是处理对象的创建的、以及对象的依赖关系!

2 spring概念

xml 复制代码
	官网地址 :http://www.spring.io

1.1 作用

js 复制代码
	
	作用:简化Java开发的。Spring不仅只是一个框架,Spring已经成为了一种生态。(与其说是Java开发,不如说是Spring开发)

	Spring可以做非常多的事情,但归根结底,支撑Sprine的仅仅是少许的基本理念,所有的理念都可以追溯到Sprine最根本的使命上!简化java开发。这是一个郑重的承诺。
	许多框架都声称在某些方面做了简化,但Spring的目标是致力于全方位的简化java开发。这势必引出更多的解释,Spring是如何简化Java开发的?
	
	为了降低Java开发的复杂性,Spring采取了以下4种关键策略:
		1、基于POI0的轻量级和最小侵入式编程;
		2、通过控制反转和依赖注入以及面向接口实现松耦合;
		3、基于切面和惯例进行声明式编程:
		4、通过切面和模板减少样板式代码,
	

1.2 历史来源

js 复制代码
	
	EJB历史:
		一个java应用层程序,是由许多个类组成的,这些类之间必然存在依赖关系,当项目越来越大,依赖关系
		越来越复杂,需要一个专业的框架来处理类之间的依赖关系,为了解决这个问题,SUN公司推出了EJB(重
		量级)专门用来解决类的依赖问题。
	
	Spring历史:
		Spring (Spring Framework)是一个开源框架,最早由Rod johnson创建,并在《Expert One-on-One:.J2EE Design andDevelopment》这本著作中进行了介绍。
		解决企业级应用开发的复杂性而创建的,使用Spring可以让简单的JavaBean实现之前只有EJB才能完成的事情。
		但Spring不仅仅局限于服务器端开发,任何java应用都能在简单性、可测试性和松耦合等方面从Spring中获益。

1.3 Spring专有名词

kotlin 复制代码
	
	+++ 组件/框架设计
					
				1)侵入式设计
							引入了框架,对现有的类的结构有影响;即需要实现或继承某些特定类。
							例如:	Struts框架(使用struts的校验功能,必须继承ActionSupport,这是一种侵入式设计)
							
				2)非侵入式设计
							引入了框架,对现有的类结构没有影响。
							例如:Hibernate框架 / Spring框架
					
		
				3)区别侵入式、非侵入式的要点是:
									引入该框架是否要继承某个特定类。
									
									如:引入struts框架,如果要实现校验功能,action必须要继承ActionSupport,这是侵入式设计,所以struts是侵入式框架。
										
										引入hibernate,虽然配置了xml配置文件,但是dao无须继承什么类。所以hibernate是非侵入式设计。
							
kotlin 复制代码
	+++ 控制反转(IOC)和依赖注入(DI)
				
				1) Inversion on Control , 控制反转 IOC
				    对象的创建交给外部容器完成,这个就做控制反转.
	
				2) dependency injection 
			        处理对象的依赖关系

	
				区别:
		 				控制反转, 解决对象创建的问题 【对象创建交给别人】
						依赖注入,在创建完对象后, 对象的关系的处理就是依赖注入 【通过set方法依赖注入】
						先有控制反转,再有依赖注入,(一个流程步骤)
kotlin 复制代码
	
	+++ AOP
			面向切面编程。切面,简单来说来可以理解为一个类,由很多重复代码形成的类。
			切面举例:事务、日志、权限;
			
js 复制代码
	
	+++ bean的各种名称:
			虽然Spring用bean或者javaBean来表示应用组件,但并不意味着Spring组件必须要遵循JavaBean规范。
			一个Spring组件可以是任何形式的POJO(POJO (Plain Ordinaryjava Obiect)简单的java对象,
			实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称)。

3 spring-frameworek框架

3.1 地位

spring framework是整个spring中最核心的一个部分。其他项目均是基于该项目进行开发或拓展的。

3.2 核心模块


3.2 结构图

js 复制代码
	1、spring-framework是一个工程(框架),里面有许多模块。每一个模块对应一个jar。比如beans、context等。
	2、没有【spring-all】这个jar。如果想使用,则必须一个一个引入。
	3、spring核心模块:core、beans、context、sprl。

	4、如果想使用spring,则必须引入这四个核心jar(core、beans、context、spel,有的版本还需引入日志jar)。
    

各个模块之间的依赖关系图

4 环境准备

4.1 spring-framework版本号说明

spring下载时

版本说明

4.2 jar包下载

js 复制代码
	官网下载教程
			https://blog.csdn.net/m0_52861000/article/details/128883819
	
	
	jar包下载地址(注意:没找到release库,只找到了SNAPSHOT库):
			https://repo.spring.io/ui/native/snapshot/org/springframework/spring/

	   
xml 复制代码
	
	下载jar包说明:	   
		   1、spring framework框架是一个工程,里面有许多模块,如core、beans、context等。
			
		   2、spring各个版本中:
					
					1)在3.0以下的版本,源码有spring中相关的所有包【spring功能 + 依赖包】,如2.5版本;
					
					2)在3.0以上的版本,源码中只有spring的核心功能包【没有依赖包】(如果要用依赖包,需要单独下载!)


		   3、下载spring framework框架时候,实质上是一个zip压缩包。
		   			
		   			压缩包里面有zip、api文档、文档约束。而zip中有该spring版本对应的模块(core、beans、context等jar)。
		   			【不存在一个包含所有模块的jar】
		   
		   3、maven依赖引入spring framework框架时,没有spring-all坐标,只有具体的模块的坐标。所以只能一个模块一个模块的引入。
1、不存在一个包含所有模块的jar
2、下载讲解

spring 库

4.3 基础案例

引入jar文件

xml 复制代码
1) 源码, jar文件:spring-framework-3.2.5.RELEASE
	
			commons-logging-1.1.3.jar           日志
			spring-beans-3.2.5.RELEASE.jar        bean节点
			spring-context-3.2.5.RELEASE.jar       spring上下文节点
			spring-core-3.2.5.RELEASE.jar         spring核心功能
			spring-expression-3.2.5.RELEASE.jar    spring表达式相关表

	以上是必须引入的5个jar文件,在项目中可以用户库管理!

在org/jsoft/demo引入applicationContext.xml(或bean.xml)配置文件

xml 复制代码
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
	
	
	<bean id="user"  class="org.jsoft.a_hello.User"></bean>

</beans>   

创建实体

java 复制代码
public class User {
	
	private String name;
	private int age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	
}

测试

java 复制代码
public class App {
	
	@Test
	public void testIOC() {
		
		//加载配置文件,创建Bean工程
		Resource rs=(Resource) new ClassPathResource("org/jsoft/a_hello/applicationContext.xml");
		BeanFactory factory=new XmlBeanFactory(rs);
		
		//获取对象
		User u=(User) factory.getBean("user");
		System.out.println(u.getAge());
	
	}
	
	@Test
	public void testIOC2() {
		
		//加载配置文件,创建Bean工程
		ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");
		
		//获取对象
		User u=(User) ac.getBean("user");
		System.out.println(u.getAge());
	
	}
}

5 spring注解驱动发展


6 IOC、DI

IOC控制反转:本质上就是将程序中原本手动创建的对象,交给spring容器去处理。

【举例:我吃包子,需要买面、油等,然后手动做。但是我如果直接去包子铺买,就省去很多事情。spring容器就是包子铺(Spring Ioc就是包子铺,对象就是包子。)】

二、基于XML配置方式的实现

1 基础环境搭建

1)新建java项目
2)导入相关的jar包

创建bin文件夹,然后复制spring框架中的lib核心包(core、beans、context、spel)

将bin文件夹设置为library库

3)创建spring配置文件

在src目录下创建applicationContext.xml配置文件

注意:通过该方法创建配置文件,必须使用idea的正式版本,idea的社区版本不能之间创建xml。


applicationContext.xml 文件内容

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>
4)创建对应的java类
java 复制代码
package com.hlp.spring.ioc.beans;

public class Car {
    private  String name;
    private String id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}
5)配置文件中注册bean
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 通过bean标签将car实例创建-->
    <bean class="com.hlp.spring.ioc.beans.Car"></bean>

</beans>
6)java代码实现
java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = ac.getBean(Car.class);
        System.out.println(car);
    }
}

注意第一次启动抛 ClassNotFoundException异常,因为缺少logging依赖,导入即可

2 IOC容器

2.1 基于XML创建IOC容器

1)方式一: BeanFactory
java 复制代码
	
	方式一:
			Resource rs=(Resource) new ClassPathResource("org/jsoft/a_hello/applicationContext.xml");
			BeanFactory factory=new XmlBeanFactory(rs);
	
java 复制代码
	@Test
	public void testIOC() {
		
		//加载配置文件,创建Bean工程
		Resource rs=(Resource) new ClassPathResource("org/jsoft/a_hello/applicationContext.xml");
		BeanFactory factory=new XmlBeanFactory(rs);
		
		//获取对象
		User u=(User) factory.getBean("user");
		System.out.println(u.getAge());
	
	}
2)方式二: ApplicationContext
java 复制代码
	ClassPathXmlApplicationContext作用:加载classpath根目录下的配置文件,创建IOC容器。

	1、加载一个配置文件。然后创建IOC容器。
      			
      			加载classpeth根类路径下
      					ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");

      			加载指定类路径下
						ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");
				
	2、加载多个配置文件。然后创建IOC容器。
      	  		
      	  		ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml","app2.xml");
java 复制代码
	public class AppStart {
	    public static void main(String[] args) {
	        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
	        Car car = ac.getBean(Car.class);
	        System.out.println(car);
	    }
	}

2.2 BeanFactory和ApplicationContext的区别

js 复制代码
	
	ApplicationContext、BeanFactory都是IOC容器。
	
	ApplicationContext是BeanFactory的子接口。ApplicationContext功能肯定比BeanFactory的功能更强大。
	
	ApplicationContext容器在初始化的时候,就会初始化Bean。
	而BeanFactory容器中的Bean是懒加载,在初始化的时候,不会初始化Bean,只有在调用getBean时,才会创建对象。
	

2.3 容器相关方法

1)一般方法
java 复制代码
	public static void main(String[] args) {
		
		//1.创建IOC容器
		ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/g_transaction_detail/applicationContext.xml");
		
		//2.根据名称获取bean对象
		DeptDao deptDao=(DeptDao) ac.getBean("deptDao");		//强制转换
		
		DeptDao deptDao2 = ac.getBean("deptDao", DeptDao.class);//利用了泛型,无需转换
		
		//3.根据类型获取bean对象(该类型只能在容器中有唯一的对象,否则报错)
		DeptDao deptDao3 = ac.getBean(DeptDao.class);
		
		//4.获取容器中bean对象的个数
		int num = ac.getBeanDefinitionCount();
		
		//5.获取容器中所有bean的名字
		String[] beanDefinitionNames = ac.getBeanDefinitionNames();
	}
	
2)getBeans( ) 方法

根据name获取

xml 复制代码
    <bean class="com.hlp.spring.ioc.beans.Car" name="myCar"></bean>
java 复制代码
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("myCar");
        System.out.println(car);
    }

根据id获取

xml 复制代码
    <bean class="com.hlp.spring.ioc.beans.Car" name="myCar" id="myCar2"></bean>
java 复制代码
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("myCar");
        System.out.println(car);
    }

根据class文件获取

xml 复制代码
    <bean class="com.hlp.spring.ioc.beans.Car" ></bean>
java 复制代码
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean(Car.class);
        System.out.println(car);
    }

如果我们根据类型去容器中获取对象,如果该类型在容器中有多个实例,那么会抛出异常信息

这时,我们可以根据组合的方式去查找

组合方式查找

xml 复制代码
    <bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean>
    <bean class="com.hlp.spring.ioc.beans.Car"  ></bean>
java 复制代码
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("car",Car.class);
        System.out.println(car);
    }

3 Bean的实例化

xml 复制代码
		SpringIOC容器,是spring核心内容。
		作用: 创建对象 & 处理对象的依赖关系
xml 复制代码
		
		IOC容器创建对象, 有几种方式:
					1) 调用无参数构造器
					2) 带参数构造器
					3) 工厂创建对象
							工厂类,静态方法创建对象
							工厂类,非静态方法创建对象

3.1 Bean标签

xml 复制代码
	<bean>:用于配置对象,让spring来创建。默认情况下调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。

			class:指定类的全限定类名,用于反射创建对象,默认情况下调用无参构造函数。如果不进行配置并且类中没有无参构造方法,则会创建失败。

			id:给对象在容器中提供一个唯一标识,用于获取对象。
			name: 设置别名,在BeanFactory的getBean("name")中可以获取相应的bean。
					
	
			scope:指定对象的作用范围
						singleton:默认值,单例的,spring加载配置文件的时候,就会创建对象
						prototype:多例的,调用getbean方法时候创建
						request:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中
						session:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中
						globalsession:WEB 项目中,应用在 Portlet 环境。如果没有 Portlet 环境那么globalSession 相当于 session


			init-method:指定类中的初始化方法名称
			destroy-method:指定类中销毁方法名称


			autowire:自动装配属性
						byName:根据属性名称注入,需要注入bean的id值要和类中属性的名称一样
						byType:根据属性类型注入,如果同类型的bean有两个或多个则不能使用类型注入
						default:默认值,不自动装配

3.2 Bean的实例化

3.2.1 构造函数
xml 复制代码
	
	1、使用无参构造创建对象(实例对象必须有无参构造)
        		<bean class="com.hlp.demo02.User" id="user"></bean>
	
	2、使用有参构造创建对象(实例对象必须有有参构造)
		        <bean class="com.hlp.demo02.User" id="user">
		            <constructor-arg name="name" value="张三"></constructor-arg>
		            <constructor-arg name="age" value="123"></constructor-arg>
		        </bean>        		
3.2.2 自定义工厂实例化
1)静态工厂创建对象

通过工厂类的静态方法获取对应的实例对象

MyBeanFactory静态工厂

java 复制代码
public class MyBeanFactory {
    public static Car  getInstance1(){
        return  new Car();
    }
}

applicationContext-static.xml 配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 静态工厂配置-->
    <bean class="com.hlp.spring.ioc.MyBeanFactory"  factory-method="getInstance1"  id="myFactory"></bean>
</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext-static.xml");
        Car car = (Car)ac.getBean("myFactory");
        System.out.println(car);
    }
}
2)动态工厂创建对象

通过工厂类的方法获取对应的实例对象

MyBeanFactory工厂

java 复制代码
public class MyBeanFactory {
    public  Car  getInstance1(){
        return  new Car();
    }
}

applicationContext-static.xml 配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 注册动态工厂-->
    <bean class="com.hlp.spring.ioc.MyBeanFactory"  id="myFactory"></bean>
	<!-- 从工厂中获取car对象-->
    <bean factory-bean="myFactory" factory-method="getInstance1"  id="xxxx"></bean>

</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext-static.xml");
        Car car = (Car)ac.getBean("xxxx");
        System.out.println(car);
    }
}
3.2.3 FactoryBean工厂实例化
1)FactoryBean介绍
js 复制代码
	 1、FactoryBean是Spring框架中的一个接口,用于创建和管理其他Bean实例的对象。
	    FactoryBean的底层工作原理是通过实现FactoryBean接口并实现其中的方法来创建和管理Bean实例。

	 2、Spring为什么使用FactoryBean
			
			一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean。
			在某些情况下,实例化 bean 过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。
	
			Spring 为此提供了一个 org.Springframework.bean.factory.FactoryBean 的工厂类接口,
			用户可以通过实现该接口定制实例化 bean 的逻辑。


	  3、FactoryBean允许我们在创建Bean实例时编写自定义的逻辑,并且可以通过其返回的实际Bean实例类型来实现更精细的依赖注入。
	    	同时,Spring框架还提供了一些内置的FactoryBean实现,
	    	例如ProxyFactoryBean和JndiObjectFactoryBean,可以帮助我们更方便地创建一些常见的Bean实例。
2)FactoryBean接口
java 复制代码
	1、getObject()方法:
				获取由此工厂创建的对象实例,可以在此方法中编写自定义的创建逻辑,例如从外部资源获取对象实例。

	2、getObjectType()方法
				获取由此工厂创建的对象实例的类型,Spring框架可以利用此方法来确定依赖注入时需要注入的具体类型。

	3、isSingleton()方法
				判断由此工厂创建的对象实例是否为单例模式。
				默认情况下,FactoryBean创建的对象实例是单例模式,但是可以通过覆盖此方法来改变对象实例的作用域。
	
	4、FactoryBean在Spring中的作用
				当配置文件中< bean>的 class 属性配置的实现类是 FactoryBean 时,通过 getBean()方法返回的不是 FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象。
				相当于FactoryBean#getObject()代理了 getBean()方法。
				
java 复制代码
public interface FactoryBean<T> {
    
    // 获取由此工厂创建的对象实例
    T getObject() throws Exception;

    // 获取由此工厂创建的对象实例的类型
    Class<?> getObjectType();

    // 判断由此工厂创建的对象实例是否为单例模式
    default boolean isSingleton() {
        return true;
    }
}
3)FactoryBean使用

User.java

java 复制代码
public class User {

    private String name;
    private int age;


    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

	...

}

UserFactoryBean .java

java 复制代码
public class UserFactoryBean implements FactoryBean<User> {

    public User getObject() throws Exception {
        User user=new User("张三",12);
        return user;
    }

    public Class<?> getObjectType() {
        return User.class;
    }

    public boolean isSingleton() {
        return false;
    }
}

applicationContext.xml

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <bean class="com.hlp.demo02.UserFactoryBean" id="factoryBean"></bean>

</beans>

App.java

java 复制代码
public class App {
    public static void main(String[] args) {

        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user=ac.getBean("factoryBean",User.class);
        System.out.println(user.getName());
        System.out.println(user.getAge());
    }
}
4)FactoryBean使用场景

1、动态创建对象

java 复制代码
public class MyFactoryBean implements FactoryBean<Object> {
    
    @Override
    public Object getObject() throws Exception {
        // 根据配置或条件动态创建对象
        if (someCondition) {
            return new MyObject();
        } else {
            return new AnotherObject();
        }
    }

    @Override
    public Class<?> getObjectType() {
        // 返回实际创建的对象的类型
        return Object.class;
    }

    @Override
    public boolean isSingleton() {
        // 返回是否为单例对象
        return true;
    }
}

2、对象的装配和初始化

java 复制代码
public class MyFactoryBean implements FactoryBean<MyObject> {

    private String name;
    private int age;

    @Override
    public MyObject getObject() throws Exception {
        // 创建对象并进行装配和初始化
        MyObject myObject = new MyObject();
        myObject.setName(name);
        myObject.setAge(age);
        return myObject;
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 设置属性值的方法
    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

3、对象的代理和包装

java 复制代码
public class MyFactoryBean implements FactoryBean<MyObject> {

    private MyObject target;

    @Override
    public MyObject getObject() throws Exception {
        // 对目标对象进行代理和包装
        MyObjectProxy proxy = new MyObjectProxy(target);
        return proxy.getProxy();
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 设置目标对象的方法
    public void setTarget(MyObject target) {
        this.target = target;
    }
}

3.3 其他注意事项

java 复制代码
	
	1、bean的名称在IOC容器不可重复。
	
	2、使用bean标签配置bean。默认bean的名称为类路径。
					    
					    <bean class="com.hlp.spring.ioc.beans.Car" ></bean>
				        
				        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
				        Car car = (Car)ac.getBean("com.hlp.spring.ioc.beans.Car");
        

	3、使用bean标签配置bean。可以使用id或name配置bean的名称。
	   name配置bean的名称,可以配置多个名称。id配置bena的名称,只能配置一个。
 					  
				1)bean属性的id和name,是bean的唯一标识。
				2)同一个spring的配置文件中,不同bean的id和name是不能相同的。否则会报错。
				3)不同的spring配置文件中,id和name可以重复。
				   此时spring针对相同的id或name采取的策略是根据DefaultListableBeanFactory类中的allowBeanDefinitionOverriding属性值来判断的。默认为true,即相同的id或name会被覆盖。如果设置为false,则会抛出异常。

	  			
1)使用bean标签配置bean。默认bean的名称为类路径。

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

      <!--  默认bean的名称为'com.hlp.spring.ioc.beans.Car'  -->
      <bean class="com.hlp.spring.ioc.beans.Car" ></bean>

</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("com.hlp.spring.ioc.beans.Car");
        System.out.println(car);
    }
}
2)使用bean标签配置bean。可以使用id或name配置bean的名称。
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

<!--      &lt;!&ndash;  使用name、id均可为bean命名。  &ndash;&gt;-->
      <bean class="com.hlp.spring.ioc.beans.Car"  name="car1" id="car2" ></bean>
      <bean class="com.hlp.spring.ioc.beans.Car"  name="car3"  ></bean>

</beans>
java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("car1");
        System.out.println(car);

        Car car2 = (Car)ac.getBean("car2");
        System.out.println(car);
    }
}
3)使用bean标签配置bean。name可以同时配置多个名称,id只能配置一个名称。
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

      <!--  默认bean的名称为'com.hlp.spring.ioc.beans.Car'  -->
<!--      <bean class="com.hlp.spring.ioc.beans.Car" ></bean>-->

<!--      &lt;!&ndash;  使用name、id均可为bean命名。  &ndash;&gt;-->
      <bean class="com.hlp.spring.ioc.beans.Car"  name="car1,car2,car3"  ></bean>

</beans>
java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("car1");
        System.out.println(car);

        Car car2 = (Car)ac.getBean("car2");
        System.out.println(car);
    }
}

4 Bean的依赖注入(DI)

DI:依赖注入(Dependency Injection)。 是 spring 框架核心IOC的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。

IOC解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
这种业务层和持久层的依赖关系,在使用 spring 之后,让 spring 来维护。

简单的说,就是坐等框架把持久层对象传入业务层,而不用自己去获取。

4.1 构造注入

java 复制代码
	构造注入:通过构造方法实现属性的注入。
	        第一步需要添加对应的有参构造方法,第二步在配置文件中添加对应的配置信息。

	
			方式一:
					<bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >
				        <constructor-arg name="id" value="1111"></constructor-arg>
				        <constructor-arg name="name" value="宝马xxx"></constructor-arg>
				        <constructor-arg name="age" value="1"></constructor-arg>
				    </bean>


			方式二:
				    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >
				        <constructor-arg index="0" value="1111"></constructor-arg>
				        <constructor-arg index="1" value="宝马xxx"></constructor-arg>
				        <constructor-arg  value="1"></constructor-arg>
				    </bean>



			方式三:【使用c标签,需引入c标签约束】
   					 <bean class="com.hlp.spring.ioc.beans.Car" c:id="11" c:name="宝马xxx" c:age="12" id="myCar" ></bean>


			方式四:【使用c标签,需引入c标签约束】
   					 <bean class="com.hlp.spring.ioc.beans.Car" c:_0="11" c:_1="宝马xxx" c:_2="12" id="myCar" ></bean>
		
1)构造注入

car.java

java 复制代码
public class Car {

    private String id;
    private  String name;
    private int  age;

    public Car(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

applicationContext.xml 配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >
        <constructor-arg name="id" value="1111"></constructor-arg>
        <constructor-arg name="name" value="宝马xxx"></constructor-arg>
        <constructor-arg name="age" value="1"></constructor-arg>
    </bean>
    

</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("myCar");
        System.out.println(car);
    }
}
2)构造注入

applicationContext.xml 配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!--        <constructor-arg name="id" value="1111"></constructor-arg>-->
<!--        <constructor-arg name="name" value="宝马xxx"></constructor-arg>-->
<!--        <constructor-arg name="age" value="1"></constructor-arg>-->
<!--    </bean>-->

    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >
        <constructor-arg index="0" value="1111"></constructor-arg>
        <constructor-arg index="1" value="宝马xxx"></constructor-arg>
        <constructor-arg  value="1"></constructor-arg>
    </bean>
    

</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("myCar");
        System.out.println(car);
    }
}
3)构造注入-c简化【使用c标签简化】

applicationContext.xml 配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!--        <constructor-arg name="id" value="1111"></constructor-arg>-->
<!--        <constructor-arg name="name" value="宝马xxx"></constructor-arg>-->
<!--        <constructor-arg name="age" value="1"></constructor-arg>-->
<!--    </bean>-->

<!--    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!--        <constructor-arg index="0" value="1111"></constructor-arg>-->
<!--        <constructor-arg index="1" value="宝马xxx"></constructor-arg>-->
<!--        <constructor-arg  value="1"></constructor-arg>-->
<!--    </bean>-->

    <bean class="com.hlp.spring.ioc.beans.Car" c:id="11" c:name="宝马xxx" c:age="12" id="myCar" ></bean>

</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("myCar");
        System.out.println(car);
    }
}
4)构造注入-c简化【使用c标签简化】

applicationContext.xml 配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!--        <constructor-arg name="id" value="1111"></constructor-arg>-->
<!--        <constructor-arg name="name" value="宝马xxx"></constructor-arg>-->
<!--        <constructor-arg name="age" value="1"></constructor-arg>-->
<!--    </bean>-->

<!--    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!--        <constructor-arg index="0" value="1111"></constructor-arg>-->
<!--        <constructor-arg index="1" value="宝马xxx"></constructor-arg>-->
<!--        <constructor-arg  value="1"></constructor-arg>-->
<!--    </bean>-->

<!--    <bean class="com.hlp.spring.ioc.beans.Car" c:id="11" c:name="宝马xxx" c:age="12" id="myCar" ></bean>-->

    <bean class="com.hlp.spring.ioc.beans.Car" c:_0="11" c:_1="宝马xxx" c:_2="12" id="myCar" ></bean>

</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("myCar");
        System.out.println(car);
    }
}

4.2 设值注入(set赋值)

xml 复制代码
	
	通过set方法给属性赋值:
		
		<bean id="user"  class="org.jsoft.c_property.User">
				<!-- 【setAge1111 -》age11111】	 -->
				<property name="age1111" value="12"></property>
		</bean>
		
		切记:给实体类赋值,实质上是调用了实体类的的setXXX方法。【如果方法名称为setAge1111,则设置bean的属性时,属性名称为age11111】
		      所以实体类赋值的变量必须有set方法,否则报错。
		      				
		【实体类赋值的成员变量,必须有set方法】		
		
1)设值注入

Car.java

java 复制代码
public class Car {

    private String id;
    private  String name;
    private int  age;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <!-- 设值注入:方式一 -->
        <bean class="com.hlp.spring.ioc.beans.Car"  id="car">
            <property name="id" value="12xxxx"></property>
            <property name="age" value="12"></property>
            <property name="name" value="12"></property>
        </bean>

        <!-- 设值注入:方式二 -->
<!--        <bean class="com.hlp.spring.ioc.beans.Car"  id="car2" p:id="xxx" p:age="12" p:name="宝马xxx"></bean>-->

</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("myCar");
        System.out.println(car);
    }
}
2)设值注入-p标签简化【必须引入p标签】

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <!-- 设值注入:方式一 -->
<!--        <bean class="com.hlp.spring.ioc.beans.Car"  id="car">-->
<!--            <property name="id" value="12xxxx"></property>-->
<!--            <property name="age" value="12"></property>-->
<!--            <property name="name" value="12"></property>-->
<!--        </bean>-->

        <!-- 设值注入:方式二 -->
        <bean class="com.hlp.spring.ioc.beans.Car"  id="car2" p:id="xxx" p:age="12" p:name="宝马xxx"></bean>

</beans>

4.3 赋值方式(根据赋值的类型来化分)

xml 复制代码
	如果初始化的属性的类型是自定义的对象,那么注入的时候可以通过ref 属性来引用
	或者直接内置bean标签注入
1 基础赋值
1)value 赋值, 直接赋值基本类型数据
xml 复制代码
	
	通过构造方法给属性赋值
		<bean id="user1"  class="org.jsoft.c_property.User">
			<constructor-arg  value="12" index="1"></constructor-arg>
			<constructor-arg  value="str" index="0"></constructor-arg>
		</bean>

	通过set方法给属性赋值
		<bean id="user2"  class="org.jsoft.c_property.User">
			<property name="name" value="王帅"></property>		
			<property name="age1111" value="12"></property>
		</bean>
	
2)ref 赋值,引用对象数据
xml 复制代码
	
	通过构造方法给属性赋值
		<bean id="str"  class="java.lang.String">
			<constructor-arg value="王帅"></constructor-arg>
		</bean>	
		<bean id="user1"  class="org.jsoft.c_property.User">
			<constructor-arg  value="12" index="1"></constructor-arg>
			<constructor-arg  ref="str" index="0"></constructor-arg>
		</bean>

	通过set方法给属性赋值
		<bean id="str"  class="java.lang.String">
			<constructor-arg value="王帅"></constructor-arg>
		</bean>	
		<bean id="user2"  class="org.jsoft.c_property.User">
			<property ref="str" value="王帅"></property>		
			<property name="age1111" value="12"></property>
		</bean>
	
3)内部Bean 赋值
xml 复制代码
		
		通过构造方法给属性赋值:
				<bean id="user1"  class="org.jsoft.c_property.User">
					<constructor-arg  value="12" index="1"></constructor-arg>
					<constructor-arg  >
						<bean class="java.lang.String">
							<constructor-arg value="sss"></constructor-arg>
						</bean>
					</constructor-arg>
				</bean>
	
	   通过set方法给属性赋值:
	
				<bean id="user2"  class="org.jsoft.c_property.User">
					<!-- 【setName -》name】	 -->
					<property name="name" >
						<bean class="java.lang.String">
							<constructor-arg value="sss"></constructor-arg>
						</bean>
					</property>
					
					<!-- 【setAge1 -》age1】	 -->
					<property name="age1111" value="12"></property>
				</bean>
4)内部Bean+级联赋值
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <bean class="com.hlp.demo02.Person" id="person1">
                <property name="personName" value="张三"></property>
         </bean>

        <bean class="com.hlp.demo02.User" id="user">
                <property name="name" value="张三"></property>
                <property name="age" value="12"></property>

                <property name="person" ref="person1" ></property>
                <property name="person.personName" value="123"></property>
        </bean>
</beans>
5)注入空值
xml 复制代码
    <bean id="book3" class="run.arbor.spring5demo.Book">
        <property name="bname" value="Java核心技术"/>
        <!-- 给bauthor设置空值 -->
        <property name="bauthor">
            <null/>
        </property>
    </bean>
6)注入特殊符号

在property标签中使用value标签,并且使用CDATA的方式来注入参数,<![CDATA[参数]]>

xml 复制代码
    <bean id="book4" class="run.arbor.spring5demo.Book">
        <property name="bname" value="Java核心技术"/>
        <!-- 给bauthor设置值为<凯 S. 霍斯特曼>
            第一种方式:把<>进行转义, &lt; 和 &gt;
            第二种方式:使用CDATA方式,<![CDATA[参数]]>
         -->
        <property name="bauthor">
            <value><![CDATA[<凯 S. 霍斯特曼>]]></value>
        </property>
    </bean>
2 集合赋值
1)list注入

Car.java

java 复制代码
public class Car {

    private String id;
    private  String name;
    private int  age;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

User.java

java 复制代码
public class User {
    private String name;

    private List<String> games;

    private List<Car> cars;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getGames() {
        return games;
    }

    public void setGames(List<String> games) {
        this.games = games;
    }

    public List<Car> getCars() {
        return cars;
    }

    public void setCars(List<Car> cars) {
        this.cars = cars;
    }
}

applicationContext.java

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <bean class="com.hlp.spring.ioc.beans.User"  name="user">
            <property name="name" value="12"></property>

            <!-- list注入基本类型属性-->
            <property name="games">
                <list>
                    <value>122</value>
                    <value>122xxx</value>
                    <value>122333ddd</value>
                </list>
            </property>

            <!-- list注入引用类型属性-->
            <property name="cars">
                <list>
                    <bean class="com.hlp.spring.ioc.beans.Car"></bean>
                    <bean class="com.hlp.spring.ioc.beans.Car"></bean>
                </list>
            </property>

        </bean>



</beans>
2)arrary注入

Car.java

java 复制代码
public class Car {

    private String id;
    private  String name;
    private int  age;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

User.java

java 复制代码
public class User {
    private String name;

    private List<String> games;

    private List<Car> cars;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getGames() {
        return games;
    }

    public void setGames(List<String> games) {
        this.games = games;
    }

    public List<Car> getCars() {
        return cars;
    }

    public void setCars(List<Car> cars) {
        this.cars = cars;
    }
}

applicationContext.java

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <bean class="com.hlp.spring.ioc.beans.User"  name="user">
            <property name="name" value="12"></property>

            <!-- array注入基本类型属性-->
            <property name="games">
                <array>
                    <value>122</value>
                    <value>122xxx</value>
                    <value>122333ddd</value>
                </array>
            </property>

            <!-- array注入引用类型属性-->
            <property name="cars">
                <array>
                    <bean class="com.hlp.spring.ioc.beans.Car"></bean>
                    <bean class="com.hlp.spring.ioc.beans.Car"></bean>
                </array>
            </property>

        </bean>



</beans>
3)map注入

Car.java

java 复制代码
public class Car {

    private String id;
    private  String name;
    private int  age;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

User.java

java 复制代码
public class User {
    private String name;

    private Map<String,String> games;
    private Map<String,Car> cars;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Map<String, String> getGames() {
        return games;
    }

    public void setGames(Map<String, String> games) {
        this.games = games;
    }

    public Map<String, Car> getCars() {
        return cars;
    }

    public void setCars(Map<String, Car> cars) {
        this.cars = cars;
    }
}

applicationContext.java

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


       <bean class="com.hlp.spring.ioc.beans.Car" id="car"></bean>

        <bean class="com.hlp.spring.ioc.beans.User"  name="user">
            <property name="name" value="12"></property>

            <!-- array注入基本类型属性-->
            <property name="games">
               <map>
                   <entry key="a1" value="111"></entry>
                   <entry key="a2" value="111"></entry>
                   <entry key="a3" value="111"></entry>
               </map>
            </property>

            <!-- array注入引用类型属性-->
            <property name="cars">
                <map>
                    <entry key="a1" value-ref="car"></entry>
                    <entry key="a2" value-ref="car"></entry>
                    <entry key="a3" value-ref="car"></entry>
                </map>
            </property>

        </bean>



</beans>

测试

java 复制代码
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User)ac.getBean("user");
        System.out.println(user);
    }
4)propertis赋值

User.java

java 复制代码
public class User {
    private String name;

    private Properties properties;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">



        <bean class="com.hlp.spring.ioc.beans.User"  name="user">
            <property name="name" value="123"></property>
            <property name="properties">
                <props>
                    <prop key="aaa" > 121212</prop>
                    <prop key="aaa2" > aaa</prop>
                    <prop key="aaa3" > bb</prop>
                </props>
            </property>
        </bean>



</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User)ac.getBean("user");
        System.out.println(user.getProperties());
    }
}
4)构建集合赋值

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <bean class="com.hlp.demo02.Person" id="person1">
               <property name="personName" value="person1"></property>
        </bean>
        <bean class="com.hlp.demo02.Person" id="person2">
                <property name="personName" value="person2"></property>
        </bean>
        <bean class="com.hlp.demo02.Person" id="person3">
                <property name="personName" value="person3"></property>
        </bean>

        <util:list id="personList">
                <ref bean="person1"/>
                <ref bean="person2"/>
                <ref bean="person3"/>
        </util:list>

        <bean class="com.hlp.demo02.User"  id="user">
                <property name="name" value="ssss" ></property>
                <property name="personList" ref="personList"></property>
        </bean>


</beans>

Person.java

java 复制代码
public class Person {
    private String personName;

    public String getPersonName() {
        return personName;
    }

    public void setPersonName(String personName) {
        this.personName = personName;
    }
}

User .java

java 复制代码
public class User {

    private String name;
    private int age;

    private List<Person> personList;
	
	set、get。。
}

App .java

java 复制代码
public class App {
    public static void main(String[] args) {

        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user=ac.getBean("user",User.class);
        System.out.println(user.getName());
        System.out.println(user.getAge());

    }
}
4 案例
案例1:ref引用对象

HelloDao.java

java 复制代码
public class HelloDao {
	
	public  User  serach() {
		return new User();
	}
}

HelloService .java

java 复制代码
public class HelloService {
	
	private HelloDao helloDao;
	
	public void setHelloDao(HelloDao helloDao) {
		this.helloDao = helloDao;
	}



	public User search() {
		return helloDao.serach();
	}
}

HelloController.java

java 复制代码
public class HelloController {
	
	private HelloService  helloService;
	
	public void setHelloService(HelloService helloService) {
		this.helloService = helloService;
	}



	public User execute() {
		return helloService.search();
	}
}

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:p="http://www.springframework.org/schema/p"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd">


	
	<!-- ## 案例:模拟aciton / service / dao -->
	<bean id="helloDao"  class="org.jsoft.c_property.HelloDao"></bean>
	
	<bean id="helloService" class="org.jsoft.c_property.HelloService">
		<property name="helloDao" ref="helloDao"></property>
	</bean>
	
	<bean id="helloAction"  class="org.jsoft.c_property.HelloController">
		<property name="helloService" ref="helloService"></property>
	</bean>
	
	
	<!-- ## 案例2(内部Bean):模拟aciton / service / dao -->
	<bean id="helloAction2"  class="org.jsoft.c_property.HelloController">
		 <property name="helloService">
		 	<bean class="org.jsoft.c_property.HelloService">
		 		<property name="helloDao">
		 			<bean class="org.jsoft.c_property.HelloDao"></bean>
		 		</property>
		 	</bean>
		 </property>
	</bean>
	
	
	
</beans>

App.java

java 复制代码
public class App {
	
	
	public static void main(String[] args) {
		
		//加载配置文件,创建Bean工程
		ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/c_property/applicationContext.xml");
		
		//获取对象
		HelloController  helloAction=(HelloController) ac.getBean("helloAction2");
		User user = helloAction.execute();
		System.out.println(user);
	
	}
	
}
案例2:内部Bean创建对象

HelloDao.java

java 复制代码
public class HelloDao {
	
	public  User  serach() {
		return new User();
	}
}

HelloService .java

java 复制代码
public class HelloService {
	
	private HelloDao helloDao;
	
	public void setHelloDao(HelloDao helloDao) {
		this.helloDao = helloDao;
	}



	public User search() {
		return helloDao.serach();
	}
}

HelloController.java

java 复制代码
public class HelloController {
	
	private HelloService  helloService;
	
	public void setHelloService(HelloService helloService) {
		this.helloService = helloService;
	}



	public User execute() {
		return helloService.search();
	}
}

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:p="http://www.springframework.org/schema/p"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd">


	
	<!-- ## 案例2(内部Bean):模拟aciton / service / dao -->
	<bean id="helloAction2"  class="org.jsoft.c_property.HelloController">
		 <property name="helloService">
		 	<bean class="org.jsoft.c_property.HelloService">
		 		<property name="helloDao">
		 			<bean class="org.jsoft.c_property.HelloDao"></bean>
		 		</property>
		 	</bean>
		 </property>
	</bean>
	
	
	
</beans>

App.java

java 复制代码
public class App {
	
	
	public static void main(String[] args) {
		
		//加载配置文件,创建Bean工程
		ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/c_property/applicationContext.xml");
		
		//获取对象
		HelloController  helloAction=(HelloController) ac.getBean("helloAction2");
		User user = helloAction.execute();
		System.out.println(user);
	
	}
	
}
案例3:构造注入使用ref注入对象

Car.java

java 复制代码
public class Car {

    private String id;
    private  String name;
    private int  age;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

User.java

java 复制代码
public class User {
    private String name;
    private Car car;

    public User(String name, Car car) {
        this.name = name;
        this.car = car;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }
}

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <!-- 构造注入使用ref注入对象-->
        <bean class="com.hlp.spring.ioc.beans.Car"  id="car123" p:id="xxx" p:age="12" p:name="宝马xxx"></bean>

        <bean class="com.hlp.spring.ioc.beans.User" id="user" >
                <constructor-arg name="name" value="123"></constructor-arg>
                <constructor-arg name="car" ref="car123"></constructor-arg>
        </bean>
        <!-- 构造注入使用c标签注入对象-->
        <!-- 构造注入使用内部bean注入对象-->

        <!-- 设值注入:方式二 -->

</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User)ac.getBean("user");
        System.out.println(user);
    }
}
案例4:构造注入使用c标签注入对象
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <!-- 构造注入使用ref注入对象-->

        <!-- 构造注入使用c标签注入对象-->
        <bean class="com.hlp.spring.ioc.beans.Car"  id="car123" p:id="xxx" p:age="12" p:name="宝马xxx"></bean>

        <bean class="com.hlp.spring.ioc.beans.User" id="user"  c:name="123" c:car-ref="car123"> </bean>
        <!-- 构造注入使用内部bean注入对象-->

        <!-- 设值注入:方式二 -->

</beans>
案例5:构造注入使用内部Bena注入对象
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <!-- 构造注入使用ref注入对象-->

        <!-- 构造注入使用c标签注入对象-->

        <!-- 构造注入使用内部bean注入对象-->
        <bean class="com.hlp.spring.ioc.beans.User" id="user" >
                <constructor-arg name="name" value="12"></constructor-arg>
                <constructor-arg name="car">
                        <bean class="com.hlp.spring.ioc.beans.Car"></bean>
                </constructor-arg>
        </bean>


</beans>
案例6:属性注入使用ref注入对象

Car.java

java 复制代码
public class Car {

    private String id;
    private  String name;
    private int  age;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

User.java

java 复制代码
public class User {
    private String name;
    private Car car;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }
}

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <!-- 属性注入使用ref注入对象-->
        <bean class="com.hlp.spring.ioc.beans.Car" name="car"></bean>
        <bean class="com.hlp.spring.ioc.beans.User" id="user" >
                <property name="name" value="123"></property>
                <property name="car" ref="car"></property>
        </bean>

        <!-- 属性注入使用c标签注入对象-->

        <!-- 属性注入使用内部bean注入对象-->



</beans>

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User)ac.getBean("user");
        System.out.println(user);
    }
}
5)属性注入使用p标签注入对象
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <!-- 属性注入使用ref注入对象-->


        <!-- 属性注入使用c标签注入对象-->
        <bean class="com.hlp.spring.ioc.beans.Car" name="car"></bean>
        <bean class="com.hlp.spring.ioc.beans.User" id="user" p:name="123" p:car-ref="car"> </bean>

        <!-- 属性注入使用内部bean注入对象-->



</beans>
6)属性注入使用内部Bena注入对象
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <!-- 属性注入使用ref注入对象-->


        <!-- 属性注入使用c标签注入对象-->

        <!-- 属性注入使用内部bean注入对象-->
        <bean class="com.hlp.spring.ioc.beans.User" >
          <property name="name" value="12"></property>
          <property name="car">
                  <bean class="com.hlp.spring.ioc.beans.Car"></bean>
          </property>
        </bean>



</beans>

4.4 自动装配

java 复制代码
		autowire:自动装配属性
					byName:根据属性名称注入,需要注入bean的id值要和类中属性的名称一样
					byType:根据属性类型注入,如果同类型的bean有两个或多个则不能使用类型注入
					default:默认值,不自动装配
						
1)autowire="byName"

按属性名称自动装配。 Spring寻找与需要自动装配的属性同名的bean。

例如,如果一个bean定义被设置为按名称自动装配,并且包含一个master属性(即,它具有setMaster(...)方法),那么Spring将查找一个名为master的bean定义并使用它来设置该属性。

xml 复制代码
<bean id="book" class="com.dhy.Factory.Book">
    <property name="name">
        <value>时间简史</value>
    </property>
    <property name="money" value="50"/>
</bean>
 <bean id="Obj" class="com.dhy.Factory.Obj" autowire="byName">
>>>>>> 案例

Person.java

java 复制代码
public class Person {
    private String personName;

	set/get

}

User .java

java 复制代码
public class User {

    private String name;
    private int age;

    private Person person123;

	set/get
}

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <bean class="com.hlp.demo02.Person" id="person123">
               <property name="personName" value="123"></property>
        </bean>

        <!-- autowire="byName"。自动给person123属性赋值-->
        <bean class="com.hlp.demo02.User" id="user" autowire="byName">
                <property name="name" value="12333"></property>
                <property name="age" value="12"></property>
                <!-- <property name="person123" ref="person123"></property>   -->
        </bean>
</beans>

App.java

java 复制代码
public class App {
    public static void main(String[] args) {

        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user=ac.getBean("user",User.class);
        System.out.println(user.getName());
        System.out.println(user.getAge());

        System.out.println(user.getPerson123().getPersonName());
    }
}
2)autowire="byType"

如果容器中恰好存在一个属性类型的bean,则使该属性自动装配。

如果存在多个,则将引发致命异常,这表明您可能无法对该bean使用byType自动装配。如果没有匹配的bean,则什么都不会发生(未设置该属性)。

以属性的类型,即Book.class,作为作为查找依据,去容器中找到这个组件

xml 复制代码
 <bean id="Obj" class="com.dhy.Factory.Obj" autowire="byType">
>>>>>> 案例

Person.java

java 复制代码
public class Person {
    private String personName;

	set/get

}

User .java

java 复制代码
public class User {

    private String name;
    private int age;

    private Person person;

	set/get...
}

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <bean class="com.hlp.demo02.Person" id="person123">
               <property name="personName" value="123"></property>
        </bean>

        <!-- autowire="byName"。自动给person123属性赋值-->
        <bean class="com.hlp.demo02.User" id="user" autowire="byType">
                <property name="name" value="12333"></property>
                <property name="age" value="12"></property>
                <!-- <property name="person123" ref="person123"></property>   -->
        </bean>
</beans>

App.java

java 复制代码
public class App {
    public static void main(String[] args) {

        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user=ac.getBean("user",User.class);
        System.out.println(user.getName());
        System.out.println(user.getAge());

        System.out.println(user.getPerson().getPersonName());
    }
}
3)自动装配全局配置

也可以定义到全局, 这样就不用每个bean节点都去写autowire="byName"

xml 复制代码
	<?xml version="1.0" encoding="UTF-8"?>
	<beans xmlns="http://www.springframework.org/schema/beans"
	    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	    xmlns:p="http://www.springframework.org/schema/p"
	    xmlns:context="http://www.springframework.org/schema/context"
	    xsi:schemaLocation="
	        http://www.springframework.org/schema/beans
	        http://www.springframework.org/schema/beans/spring-beans.xsd
	        http://www.springframework.org/schema/context
	        http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName">   根据名称自动装配(全局)
		
		<!-- ###############自动装配############### -->  
		<bean id="userDao" class="cn.itcast.d_auto.UserDao"></bean>	
		<bean id="userService" class="cn.itcast.d_auto.UserService"></bean>
		<bean id="userAction" class="cn.itcast.d_auto.UserAction"></bean>
	</beans>  
	

5 Bean的作用域

java 复制代码
	scope:指定对象的作用范围

				singleton:默认值,单例的,spring加载配置文件的时候,就会创建对象
				prototype:多例的,调用getbean方法时候创建

				request:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中
				session:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中
				globalsession:WEB 项目中,应用在 Portlet 环境。如果没有 Portlet 环境那么globalSession 相当于 session
1)单例

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


        <bean class="com.hlp.demo02.Person" id="person1" scope="singleton">
                <property name="personName" value="person1"></property>
        </bean>


</beans>

App.java

java 复制代码
public class App {

    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Person bean1 = ac.getBean(Person.class);
        Person bean2 = ac.getBean(Person.class);

        System.out.println("bean1"+bean1);
        System.out.println("bean2"+bean2);
    }
}
2)多例

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


        <bean class="com.hlp.demo02.Person" id="person1" scope="prototype">
                <property name="personName" value="person1"></property>
        </bean>


</beans>

App.java

java 复制代码
public class App {

    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Person bean1 = ac.getBean(Person.class);
        Person bean2 = ac.getBean(Person.class);

        System.out.println("bean1"+bean1);
        System.out.println("bean2"+bean2);
    }
}

6 Bean的生命周期

xml 复制代码
		<bean id="user"  class="org.jsoft.a_hello.User"  init-method="user_init"   destroy-method="user_destoty" ></bean>

		
				init-method="init_user"     对应对象的init_user方法,
				                            在对象创建爱之后执行
				
				destroy-method="xxx"  在调用容器对象的destriy方法时候执行,
				                      (只有容器用实现类,才能调用容器的销毁方法)
>>>>>> 案例

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:p="http://www.springframework.org/schema/p"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd">


	<bean id="user"  class="org.jsoft.a_hello.User"  init-method="user_init"   destroy-method="user_destoty" ></bean>


</beans>

User.java

java 复制代码
public class User {
	
	private String name;
	private int age;
	
	public User() {
		super();
		System.out.println("对象创建完毕");
	}
	
	public void user_init() {
		System.out.println("创建对象之后,初始化");
	}
	
	public void user_destoty(){
		System.out.println("IOC容器销毁,调用");
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	
}

App.java

java 复制代码
public class App_bean {
	
	@Test
	public void testIOC() {
		
		//加载配置文件,创建Bean工程
		//ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");
		
		//加载配置文件,创建Bean工程【用容器对象的实现类,因为要调用容器的销毁方法】
		ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");
		System.out.println("---IOC容器初始化完毕---");
		
		//获取对象
		User u=(User) ac.getBean("user");

		System.out.println(u);
		
		//销毁IOC容器
		ac.destroy();

	}
}

7 applicationContext总分配置文件

总分配置文件配置

>>>>>> bean.xml
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	 http://www.springframework.org/schema/beans/spring-beans.xsd
     	 http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
     	 http://www.springframework.org/schema/tx/spring-tx.xsd">
     	
     	
    	<import resource="resource/bean-base.xml"/>
     	<import resource="resource/bean-dao.xml"/>
       	<import resource="resource/bean-service.xml"/>
       	<import resource="resource/bean-controller.xml"/>
    
</beans>
>>>>>> resource/bean-base.xml
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	 http://www.springframework.org/schema/beans/spring-beans.xsd
     	 http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
     	 http://www.springframework.org/schema/tx/spring-tx.xsd">
     	 
     	 
     	 
	<!-- 1) 连接池对象实例 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="user" value="root"></property>
		<property name="password" value="root"></property>
		<property name="initialPoolSize" value="3"></property>
		<property name="maxPoolSize" value="6"></property>
		<property name="maxIdleTime" value="1000"></property>
	</bean>
    
  	<!-- 2) SessionFactory对象实例 -->
   	<!-- ### >>> 方式 3所有的配置全部都在Spring配置文件中完成 -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<!-- ## 注入连接池对象 -->
		<property name="dataSource" ref="dataSource"></property>
		
		<!-- ## hibernate常用配置 -->
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
		
		
		<!-- hibernate映射配置 
		<property name="mappingLocations">
			<list>
				<value>classpath:cn/itcast/entity/*.hbm.xml</value>
			</list>
		</property>
		-->
		<!-- ## hibernate映射配置 -->
		<property name="mappingDirectoryLocations">
			<list>
				<value>classpath:org/hlp/entity</value>
			</list>
		</property>
		
	</bean>
	

      
    <!-- 3) 事务配置 -->
    <!-- ## a.配置事务管理器 -->
    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    
    <!-- ## b.配置事务增强 -->
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
				<tx:method name="get*"  read-only="true"/>
				<tx:method name="find*" read-only="true"/>
				<tx:method name="*" read-only="false"/>
		</tx:attributes>
	</tx:advice>
	
    <!-- ## c.配置Aop -->
	<aop:config >
		<!-- 定义切入点表达式 -->
		<aop:pointcut expression="execution(* org.hlp.dao.*.*(..))" id="pt"/>
			
		<!-- 相当于aop:acpect中定义的环绕通知 -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
	</aop:config>
    
	<bean id="adminDao" class="org.hlp.dao.AdminDao">
		<property name="sf" ref="sessionFactory"></property>
	</bean>
    
    
</beans>
>>>>>> resource/bean-dao.xml
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	 http://www.springframework.org/schema/beans/spring-beans.xsd
     	 http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
     	 http://www.springframework.org/schema/tx/spring-tx.xsd">
     	 
   
	<bean id="adminDao" class="org.hlp.dao.AdminDao">
		<property name="sf" ref="sessionFactory"></property>
	</bean>
    
   	<bean id="deptDao" class="org.hlp.dao.DeptDao">
		<property name="sf" ref="sessionFactory"></property>
	</bean>
	
	<bean id="empDao" class="org.hlp.dao.EmpDao">
		<property name="sf" ref="sessionFactory"></property>
	</bean>
    
</beans>
>>>>>> resource/bean-service.xml
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	 http://www.springframework.org/schema/beans/spring-beans.xsd
     	 http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
     	 http://www.springframework.org/schema/tx/spring-tx.xsd">
     	 
   
	<bean id="adminService" class="org.hlp.service.impl.AdminService">
		<property name="adminDao" ref="adminDao"></property>
	</bean>
	
	<bean id="empService" class="org.hlp.service.impl.EmpService">
		<property name="empDao" ref="empDao"></property>
	</bean>
	
	<bean id="deptService" class="org.hlp.service.impl.DeptService">
		<property name="deptDao" ref="deptDao"></property>
	</bean>
    
    
</beans>

三、基于XML配置方式+注解方式的实现

3.1 基础实现

1)添加AOP依赖支持
xml 复制代码
	在使用xml方式时,核心包只需要使用core、beans、context、jar。
	基于注解的方式需要用到AOP的支持,所以我们需要添加AOP的依赖。
2)添加扫描

通过context标签component-scan属性指定扫描路径

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">


      <!-- 添加扫描路径-->
      <!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类-->
      <context:component-scan base-package="com.hlp.spring.ioc.beans"></context:component-scan>
</beans>
3)使用@Component注解

Car.java

java 复制代码
@Component
public class Car {

    private String id;
    private  String name;
    private int  age;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
4)测试
java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("car");
        System.out.println(car);
    }
}

3.2 context:component-scan标签,开启注解扫描

context:component-scan标签,配置扫描路径。

xml 复制代码
		
	1、使用步骤
			1)先引入context名称空间
					xmlns:context="http://www.springframework.org/schema/context"
			2)开启注解扫描
					<context:component-scan base-package="cn.itcast.e_anno2"></context:component-scan>
			3)使用注解
					通过注解的方式,把对象加入ioc容器。
	
	2、使用
		 	1)使用context:component-scan标签可以指定一个或多个容器扫描路径。
		 	2)使用context:component-scan标签可以指定扫描哪些对象。
		 	
		 	
1)使用context:component-scan标签指定多个容器扫描路径

方式一:使用多个context:component-scan标签指定多个配置包

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

		
	  <!----->
      <!-- 添加扫描路径-->
      <!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类-->
      <context:component-scan base-package="com.hlp.spring.ioc.beans"></context:component-scan>

      <context:component-scan base-package="com.hlp.spring.ioc.beans2"></context:component-scan>

</beans>

方式二:使用一个context:component-scan标签指定多个配置包

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

		
	  <!----->
      <!-- 添加扫描路径-->
      <!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类-->
      <context:component-scan base-package="com.hlp.spring.ioc.beans,com.hlp2"></context:component-scan>

</beans>
2)使用context:component-scan标签配置注解生效

使用context:component-scan开启注解扫描。配置只扫描哪个注解。

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">


      <!-- 添加扫描路径-->
      <!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类-->

      <!--不使用@Component、@Controller、@Service、@Repository注解。-->
      <context:component-scan base-package="com.hlp.spring.ioc.beans"  use-default-filters="false"></context:component-scan>


      <!--不使用@Component、@Controller、@Service、@Repository注解。仅使用@Component-->
      <context:component-scan base-package="com.hlp.spring.ioc.beans"  use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
      </context:component-scan>


</beans>

使用context:component-scan开启注解扫描。配置不扫描哪个注解。

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">


      <!--使用@Component、@Controller、@Service、@Repository注解。默认值。-->
      <context:component-scan base-package="com.hlp.spring.ioc.beans"  use-default-filters="true"></context:component-scan>

      <!--使用@Component、@Controller、@Service、@Repository注解。@Controller注解除外-->
      <context:component-scan base-package="com.hlp.spring.ioc.beans"  use-default-filters="true">
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
      </context:component-scan>



</beans>

3.3 @Component、@Controller、@Service、@Repository注解

js 复制代码
	1、使用@Component、@Controller、@Service、@Repository标注类,用于注册IOC容器。
	   注解后可以被spring框架所扫描并注入到spring容器来进行管理		
	   						【相当于spring配置文件中的bean标签。】


	2、使用方式:标注类时,默认bean的名称为标注类的'首字母小写形式'。同时也可以指定bean的名称。
	 					
	 					1)bean的名称为car。		
	 							@Component
	 							public class Car {...}
	 							
	 					2)bean的名称为car111。		
								@Component("car111")
	 							public class Car {...}
1)区别
xml 复制代码
	1、@Controller层是spring-mvc的注解,具有将请求进行转发,重定向的功能。	
	
	2、@Service层是业务逻辑层注解,这个注解只是标注该类处于业务逻辑层。		
	   
	3、@Repository注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。
				   
    4、@Component是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能,
	   
	   			当你的一个类被@Component所注解,
	   			那么就意味着同样可以用@Repository, @Service, @Controller来替代它,
	   			同时这些注解会具备有更多的功能,而且功能各异。
2)使用
>>>>>> 默认bean的名称类名首字母小写

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

      <context:component-scan base-package="com.hlp.spring.ioc"></context:component-scan>
</beans>

Car.java

java 复制代码
@Component
public class Car {

    private String id;
    private  String name;
    private int  age;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("car");
        System.out.println(car);
    }
}
>>>>>> 指定bean的名称

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

      <context:component-scan base-package="com.hlp.spring.ioc"></context:component-scan>
</beans>

Car.java

java 复制代码
@Component("car123")
public class Car {

    private String id;
    private  String name;
    private int  age;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

测试

java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = (Car)ac.getBean("car123");
        System.out.println(car);
    }
}

3.4 @Resource注解和@Autowire

在注解的场景下依赖注入我们可以通过 @Resource和@Autowired实现.

他们的区别是@Resource默认是根据name属性来查找的,

而@Autowired注解默认是根据类型査找的,@Autowired需要和@Qualifier配合实现基于name的查找
@Autowired和@Resource都可以用来装配bean,都可以写在字段上,或者方法上。

java 复制代码
	@Resource 注解和 @Autowired 注解都是在 Spring Framework 中进行依赖注入的注解,但它们之间有一些区别:
	
		1. 来源不同:@Autowired属于Spring的;@Resource为JSR-250标准的注释,属于J2EE的。
				
						@Resource 注解是由 Java EE 提供的注解,它定义在 javax.annotation.Resource 包下。
						@Autowired 注解是由 Spring 提供的注解,它定义在 org.springframework.beans.factory.annotation.Autowired 包下。
		
		2. 依赖注入策略不同:@Autowired默认按类型装配。@Resource默认按照名称进行装配。
		
						@Resource 注解默认按照名称进行依赖注入,如果有多个具有相同类型的依赖,可以使用 name 属性指定依赖的名称。
						@Autowired 注解默认按照类型进行依赖注入,如果有多个具有相同类型的依赖,可以使用 @Qualifier 注解或者 @Primary 注解指定依赖的名称或主要依赖。

		
		3. 注解属性不同:	
						@Resource 注解可以添加 name 属性来指定依赖的名称,还可以添加 mappedName 属性来指定依赖的 JNDI 名称。
						@Autowired 注解可以添加 required 属性来指定依赖是否必须,默认为 true。

	

3.4.1 @Resource

java 复制代码
	 @Resource注解:

		 1、@Resource 是 Java EE 的注解之一,它用于进行依赖注入。

		 2、@Resource 注解可以应用于字段、方法上。		 
		 				
		 				>>>  @Resource标注成员变量,查找IOC容器(默认根据变量名称),给变量赋值。		 							
						
						>>>  @Resource标注方法,查找IOC容器(默认根据方法参数名),给方法的参数赋值。
						     【标注的方法只能有一个参数,否则报错】

		 3、使用方式	 
				  1)不写name属性: @Resource
				  			a、默认按照byName的方式进行匹配注入。如果匹配不到,再按 byType的方式进行匹配。
				  			
				  			b、当注解写在字段上时,默认取字段名进行按照名称查找。							
							c、如果注解写在xxx方法上,默认取参数的名称进行装配。【xxx方式仅支持一个参数,否则报错】
				  
				  2)写name属性: @Resource(name="xxxx")    
				  			指定名称,仅能按照byName的方式进行匹配注入。如果找不到,则报错。
3.4.1.1 使用详解
java 复制代码
		 1)@Resource标注在成员变量上
		 
		 		 	@Resource标注在成员变量上:
		 		 				  默认查询IOC容器中name或id为"person123"的对象,
		   		 				  如果有,则注入。如果没有,则按照类型查找。
				    				
				    				@Resource
				    				private Person person123;


		 
					@Resource(name="personz")标注在成员变量上:
		 							查询IOC容器中name或id为"personz"的对象,
		    						如果有,则注入。如果没有,则报错。

	    							@Resource(name="personz")
	    							private Person person;

					
java 复制代码
		 3)@Resource标注在方法:
		 				@Resource标注在方法:
		 							查询IOC容器中name或id为"personX1"的对象,
		    						如果有,则注入。如果没有,则根据类型查找。
		   
		   							@Resource
	    							public void  m1(Person personX1){

									}

		 				@Resource(name="personz")标注在方法:
		 							查询IOC容器中name或id为"personz"的对象,
		    						如果有,则注入。如果没有,则报错。

	   								 @Resource(name="personz")
	   				 				 public void  m1(Person person){

									 }
									 
1)@Resource 默认按照byName的方式进行匹配注入。如果匹配不到,再按 byType的方式进行匹配。

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


       <bean class="com.hlp.demo02.Person" id="person123"></bean>

       <context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>

MySomeService.java

java 复制代码
@Component
public class MySomeService {

    @Resource
    private Person person;


    public void print(){
        System.out.println(person);
    }
}

测试

java 复制代码
@Component
public class App {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        MySomeService someService = ac.getBean(MySomeService.class);
        someService.print();;
    }
}
2)@Resource(name="xxxx") 指定名称,则只能根据名称查找。找不到,则会报错。

User.java

js 复制代码
@Component("abc123")
public class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

ServiceImpl.java

java 复制代码
@Component
public class ServiceImpl {

    @Resource(name="abc123")
    private  User user;

    public User getUser() {
        return user;
    }
}

测试

java 复制代码
@Component
@ComponentScan
public class AppStart {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppStart.class);

        ServiceImpl serviceImpl = (ServiceImpl)ac.getBean("serviceImpl");
        System.out.println(serviceImpl.getUser());
    }
}
3.4.1.2 案例
>>>>>> @Resource标注成员变量

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


       <bean class="com.hlp.demo02.Person" id="person123"></bean>

       <context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>

MySomeService.java

java 复制代码
@Component
public class MySomeService {

    @Resource
    private Person person123;

    public void print(){
        System.out.println(person);
    }
}

App .java

java 复制代码
@Component
public class App {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        MySomeService someService = ac.getBean(MySomeService.class);
        someService.print();;
    }
}
>>>>>> @Resource标注方法

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


       <bean class="com.hlp.demo02.Person" id="person123"></bean>

       <context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>

MySomeService.java

java 复制代码
@Component
public class MySomeService {

    private Person person123;
	
	@Resource	
	public  void  xxx(Person person123){
		this.person123=person123;
	}

    public void print(){
        System.out.println(person);
    }
}

App .java

java 复制代码
@Component
public class App {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        MySomeService someService = ac.getBean(MySomeService.class);
        someService.print();;
    }
}
>>>>>> @Resource(name = "person123")标注成员变量

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


       <bean class="com.hlp.demo02.Person" id="person123"></bean>

       <context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>

MySomeService.java

java 复制代码
@Component
public class MySomeService {

    @Resource(name = "person123")
    private Person person;

    public void print(){
        System.out.println(person);
    }
}

App .java

java 复制代码
@Component
public class App {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        MySomeService someService = ac.getBean(MySomeService.class);
        someService.print();;
    }
}
>>>>>> @Resource(name = "person123")标注方法

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


       <bean class="com.hlp.demo02.Person" id="person123"></bean>

       <context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>

MySomeService.java

java 复制代码
@Component
public class MySomeService {

    private Person person123;
	
	@Resource(name = "person123")
	public  void  xxx(Person person123){
		this.person123=person123;
	}

    public void print(){
        System.out.println(person);
    }
}

App .java

java 复制代码
@Component
public class App {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        MySomeService someService = ac.getBean(MySomeService.class);
        someService.print();;
    }
}

3.4.2 @Autowired

java 复制代码
	 @Autowired注解:

		 1、spring提供注解。注入时,默认根据bean的类型查找。同时也可以指定名称查找。
		 2、@Autowired 注解可以应用于标注在成员变量、构造方法、普通方法上。		 
		 			
java 复制代码
		
		3、使用
				1)@Autowired:按照类型查找
				 			@Autowired 标注成员变量:查找IOC容器【与变量同类型的对象】,并注入	
				 						
				 			   			 	@Autowired
		    								private Person person;
					
		
				 			@Autowired 标注构造方法:查找IOC容器【与构造方法的参数同类型的对象】,并注入	
										   
										    @Autowired
										    public MySomeService(Person person2){
										        this.person=person2;
										    } 			
		
		
				 			@Autowired 标注方法:查找IOC容器【与方法的参数同类型的对象】,并注入											   
										    @Autowired
										    public void ser(Person person123){
										        this.person=person123;
										    }

										   
										   注意:方法可以无参。IOC初始化后也会调用该方法。类似于init-method
										    @Autowired
										    public void ser(){
										        system.out.print("123")
										    }
										    


				1)@Autowired配合@Qualifier("xxx")。按照指定名称查找
				 			
				 	     @Autowired+@Qualifier("person123")标注成员变量:
				 	     					根据指定名称查找IOC容器中对象,并注入	
				 						
				 			   			     @Autowired
										     @Qualifier("person123")
										     private Person person123;
					
				 			
				 		@Autowired+@Qualifier("person123")标注方法:
				 							查找IOC容器中同类型的对象,并注入	
										   
										    @Autowired
										    @Qualifier("person123")
										    public void ser(Person person123){
										        this.person=person123;
										    }
		
				 		@Autowired+@Qualifier("person123")不能标注构造方法
		
		
1)@Autowired 默认根据类型查找。

User.java

js 复制代码
@Component("abc123")
public class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

ServiceImpl.java

java 复制代码
@Component
public class ServiceImpl {

    @Autowired
    private  User user;

    public User getUser() {
        return user;
    }
}

测试

java 复制代码
@Component
@ComponentScan
public class AppStart {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppStart.class);

        ServiceImpl serviceImpl = (ServiceImpl)ac.getBean("serviceImpl");
        System.out.println(serviceImpl.getUser());
    }
}
2)@Autowired + @@Qualifier(name="xxx") 根据名称查找

User.java

js 复制代码
@Component("abc123")
public class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

ServiceImpl.java

java 复制代码
@Component
public class ServiceImpl {

    @Autowired
    @Qualifier("abc123")
    private  User user;

    public User getUser() {
        return user;
    }
}

测试

java 复制代码
@Component
@ComponentScan
public class AppStart {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppStart.class);

        ServiceImpl serviceImpl = (ServiceImpl)ac.getBean("serviceImpl");
        System.out.println(serviceImpl.getUser());
    }
}

四、基于JavaConfig配置类方式的实现

xml 复制代码
	在Spring3.x之后开始支持]ava配置类的形式,从而舍弃配置文件的方式。

4.1 基本实现

xml 复制代码
	Java配置文件需要通过@Configuration注解标注,需要加载的实例需要通过@Bean注解标注
1)MyConfig.java 配置类
java 复制代码
@Configuration
@ComponentScan
public class MyConfig {

    @Bean
    public User user(){
        return  new User();
    }
}
2)Car.java
java 复制代码
@Component
public class Car {

    private String id;
    private  String name;
    private int  age;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
3)User.java
java 复制代码
public class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
4)测试
java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
        Car car = (Car)ac.getBean("car");
        System.out.println(car);

        User user = (User)ac.getBean("user");
        System.out.println(user);
    }
}

4.2 AnnotationConfigApplicationContext容器

xml 复制代码
   AnnotationConfigApplicationContext作用:加载配置类,创建IOC容器。
      
java 复制代码
 	    
        1、指定配置类,创建IOC容器
        		1)使用AnnotationConfigApplicationContext创建IOC容器,指定配置类。

           		2)配置类必须被@Configuration或@Comonent、@Controller等价注解所标注。配置类的作用相当于applicatonContext.xml配置文件
				
				3)基础用法
						a、指定一个或多个配置类,创建IOC容器
					        	
					        		ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
				
					        		ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class,MyConfig2.class);
					
						c、指定一个或多个扫描路径,创建IOC容器
					        	
					        		ApplicationContext ac=new AnnotationConfigApplicationContext("com.hlp.spring.ioc");
				
					        		ApplicationContext ac=new AnnotationConfigApplicationContext("com.hlp.spring.ioc","com.hlp.spring.ioc2");


        2、不指定配置类,创建IOC容器。【手动注册配置类】
			   		
				   		//创建无配置类的IOC容器
				        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
				
				        //手动注册配置类【注册后必须刷新】
				        ac.register(MyConfig.class);
				        ac.refresh();
			
		
1)指定配置类,注册IOC容器
java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);

        Car car = (Car)ac.getBean("car");
        System.out.println(car);

    }
}
2)不指定配置类,注册IOC容器。手动注册配置类
java 复制代码
public class App {
    public static void main(String[] args) {

        //创建无配置类的IOC容器
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();

        //手动注册配置类【注册后必须刷新】
        ac.register(MyConfig.class);
        ac.refresh();

        Object dev = ac.getBean("dev");
        System.out.println(dev);
    }
}

4.3 @Configuration Java配置类

js 复制代码
	1、使用@Configuration的作用:配置java配置类。相当于spring配置文件。
	2、@Configuration与@Compoonent、@Controller、@Service、@Repository注解等价。

案例

java 复制代码
@Configuration
@ComponentScan
public class MyConfig {

    @Bean
    public User user(){
        return  new User();
    }
}
java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
        Car car = (Car)ac.getBean("car");
        System.out.println(car);

        User user = (User)ac.getBean("user");
        System.out.println(user);

    }
}

4.4 @ComponentScan、@ComponentScans注解,配置扫描包

java 复制代码
	1、@ComponentScan或@ComponentScans作用:
	
	        1)在基于java配置类的方式中,一般结合@Configuration使用,实现IOC容器。	        
		    2)用于配置扫描路径。相当于applicationContext.xml中的context:component-scan标签。	
js 复制代码
     2、@ComponentScan指定扫描路径,可以指定包名,也可以指定xxx.class类文件
   			指定包名:扫描当前包下的文件以及子包文件,创建Bean。
			指定类文件:扫描当前类所在包的文件及其子包文件,创建Bean。
			
				1)默认扫描当前标注类所在包及其子包的类。
							@ComponentScan
		
				2)指定一个扫描路径
							       @ComponentScan("com.hlp.spring.ioc.beans")
							       @ComponentScan({"com.hlp.spring.ioc.beans"})
		
								   @ComponentScan(basePackages = "com.hlp.spring.ioc.beans")
								   @ComponentScan(basePackages = {"com.hlp.spring.ioc.beans"})
		
		
				3)指定多个扫描路径
								   @ComponentScan({"com.hlp.spring.ioc.beans","com.hlp.spring.ioc.beans"})
								   @ComponentScan(basePackages = {"com.hlp.spring.ioc.beans","com.hlp.spring.ioc.beans"})
			   
			   
			    4)指定一个或多个类文件
			                       @ComponentScan(basePackageClasses={Car.class})
			                       @ComponentScan(basePackageClasses={Car.class,User.class})

	
	
	3、@ComponentScan其他属性
									@Configuration
									@ComponentScan(basePackages = "com.hlp.spring.ioc.beans"
									        ,useDefaultFilters=false
									        ,includeFilters ={@ComponentScan.Filter(Controller.class)} )
									public class MyConfig {
									
									    @Bean("myUser")
									    public User myUser(){
									        return  new User();
									    }
									 }
js 复制代码
     4、使用@ComponentScans指定扫描路径,作用与@ComponentScan等价
1)使用@ComponentScan指定扫描路径

MyConfig.java

java 复制代码
@Configuration
@ComponentScan("com.hlp.spring.ioc.beans")
public class MyConfig {

    @Bean("myUser")
    public User myUser(){
        return  new User();
    }
}

测试

java 复制代码
public class AppStart {

    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
        User user = (User)ac.getBean("myUser");
        System.out.println(user);
    }
}
2)使用@ComponentScans指定扫描路径

MyConfig.java

java 复制代码
@Configuration
@ComponentScans({
        @ComponentScan({"com.hlp.spring.ioc"}),
        @ComponentScan({"com.hlp.spring.ioc.beans"})
}) public class MyConfig {

    @Bean("myUser")
    public User myUser(){
        return  new User();
    }
}

测试

java 复制代码
public class AppStart {

    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
        User user = (User)ac.getBean("myUser");
        System.out.println(user);
    }
}
3)属性示例

MyConfig.java

java 复制代码
@Configuration
@ComponentScan(basePackages = "com.hlp.spring.ioc.beans"
        ,useDefaultFilters=false
        ,includeFilters ={@ComponentScan.Filter(Controller.class)} )
@ComponentScan(basePackages = "com.hlp.spring.ioc.beans"
        ,useDefaultFilters=true
        ,excludeFilters ={@ComponentScan.Filter(Controller.class)} )
public class MyConfig {

    @Bean("myUser")
    public User myUser(){
        return  new User();
    }
}

测试

java 复制代码
public class AppStart {

    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
        User user = (User)ac.getBean("myUser");
        System.out.println(user);
    }
}

4.5 @Bean注解

js 复制代码
	
	@Bean
		1、相当于applicationContext中的bean标签。
	    2、一般在@Configuration标注的类中使用。由于@Configuration与其他@Component等标签等价,所以也可以在@Component等标签中标注的类中使用。
		

		3、默认注册的bean的名称为标注的方法名。同时也可以指定bean的名称
				
				默认注册bean的名称为方法名myUser
					    @Bean
					    public User myUser(){
					        return  new User();
					    }
				
				指定bean的名称为abc123
					    @Bean("abc123")
					    public User myUser(){
					        return  new User();
					    }

		4、@Bean标注的方法有参数,会自动注入参数对象。
			   1)@Bean标注的方法可以有多个参数。spring默认会根据参数类型查找IOC容器注入参数。如果找不到,就报错。
		       2)@Bean标注的方法可以有多个参数。通过@Qualifier("name")注解标注参数,spring会根据名称查找IOC容器注入参数。如果找不到,就报错。
1) 默认注册的bean的名称为标注的方法名
java 复制代码
@Configuration
@ComponentScan
public class MyConfig {

    @Bean
    public User myUser(){
        return  new User();
    }
}
java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
//        Car car = (Car)ac.getBean("car");
//        System.out.println(car);

        User user = (User)ac.getBean("myUser");
        System.out.println(user);

    }
}
2) 指定bean的名称
java 复制代码
@Configuration
@ComponentScan
public class MyConfig {

    @Bean("abc123")
    public User myUser(){
        return  new User();
    }
}
java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
//        Car car = (Car)ac.getBean("car");
//        System.out.println(car);

        User user = (User)ac.getBean("abc123");
        System.out.println(user);

    }
}
3) @Bean标注有多个参数方法,默认会根据参数类型查找IOC并将对象注入到参数中

DataSourceConfig.java

java 复制代码
@Component("abc")
public class DataSourceConfig {

    @Bean
    public DataSource dataSource(){
        DriverManagerDataSource dataSource=new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setUrl("jdbc:mysql://localhost:3306/demo");
        return dataSource;
    }


    @Bean
    public JdbcTemplate testBean(DataSource aa, DataSource a3){
        System.out.println(aa);
        System.out.println(a3);
        return null;
    }

}

App.java

java 复制代码
@Component
@ComponentScan
public class App {
    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(App.class);
    }
}
4) @Bean标注有多个参数方法,通过(@Qualifier("springDS2")标注参数,会根据名称查找IOC并将对象注入到参数中

DataSourceConfig.java

java 复制代码
@Component("abc")
public class DataSourceConfig {

    @Bean("db1")
    public DataSource dataSource(){
        DriverManagerDataSource dataSource=new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setUrl("jdbc:mysql://localhost:3306/demo");
        return dataSource;
    }

    @Bean("db2")
    public DataSource dataSource(){
        DriverManagerDataSource dataSource=new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setUrl("jdbc:mysql://localhost:3306/demo");
        return dataSource;
    }


    @Bean
    public JdbcTemplate testBean((@Qualifier("db1")DataSource aa){
        System.out.println(aa);
        return null;
    }

}

App.java

java 复制代码
@Component
@ComponentScan
public class App {
    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(App.class);
    }
}

4.6 @Conditional、@Profile条件注解

1 @Conditional
js 复制代码
	
	@Conditional注解:配置@Bean注解使用,决定是否将注册的Bean注入到IOC容器中
		
			1、使用步骤
						1)编写一个类MyConditional,实现Condition接口中的matches方法。
						2)使用@Conditional(MyConditional.class)进行标注注册的bean。
				
						3)如果MyConditional实现的matches返回true,则注入标注bean,如果为false,则不注入标注bean。
			
			2、使用方式
				
						1)指定一个条件
							    //如果MyConditional中的matches方法返回true,则注入。否则不注入。
								@Conditional(MyConditional.class)


							    //如果MyConditional中的matches方法返回true,则注入。否则不注入。
								@Conditional({MyConditional.class})								
								
								
						2)指定两个条件
								//如果MyConditional和MyConditional2中的matches方法都返回true,则注入。否则不注入。
								@Conditional({MyConditional.class,MyConditional2.class})

	
1)自定义MYConditional类,实现Condition接口。

该方法返回true,则允许注册标注bean。否则不允许注册标注bean。

java 复制代码
public class MYConditional implements Condition {


    //matches方法逻辑:加载"com.hlp.spring.ioc.User"类。如果为空,则返回false。如果不为空,则返回true
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        ClassLoader classLoader = conditionContext.getClassLoader();
        try {
            Class<?> clazz = classLoader.loadClass("com.hlp.spring.ioc.User");
            if(clazz!=null){
                return true;
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return false;
    }
}
2)配置使用条件
java 复制代码
@Configuration
@ComponentScan
public class MyConfig {

    @Bean("myUser")
    @Conditional({MYConditional.class})
    public User myUser(){
        return  new User();
    }
}
3)测试
java 复制代码
public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
        User user = (User)ac.getBean("myUser");
        System.out.println(user);

    }
}
2 @Profile 注解
js 复制代码
	 @Profile 注解:
	 	 1、@Profile注解继承了@Conditional条件注解,同时指定了条件类。
	 					 @Conditional({ProfileCondition.class})
	 					 
	 	 2、条件类ProfileCondition.class是Spring提供的,内置的条件类。
	 	   				其作用是读取Environment中的activeProfile属性设置的值。
	 	   				与@Profile指定的值进行比较。如果相同,则注入该bean。如果不同,则不注入。
	 	   				 	 
	
1)作用

@Profile使用时,指定value值。

@Profile注解源码:

该注解继承了@Conditional注解。@Conditional注解中也指定了条件类ProfileCondition.class
ProfileCondition源码

该条件类的作用是:读取环境变量中的activeProfile属性,与当前@Profile指定值比较,如果相同,则返回true,即允许注入。否则不允许注入。

2)使用案例

Datasource.java

java 复制代码
public class Datasource {
    private String url;
    private String password;
    private String name;

    public Datasource(String url, String password, String name) {
        this.url = url;
        this.password = password;
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    @Override
    public String toString() {
        return "Datasource{" +
                "url='" + url + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

MyConfig.java

java 复制代码
@Configuration
public class MyConfig {

	//@Profile("dev"):读取环境变量中activeProfile属性,如果属性值与"dev"相同,则注入该bean。
    @Bean("ds")
    @Profile("dev")
    public Datasource  datasource1(){
        return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");
    }

	//@Profile("dev"):读取环境变量中activeProfile属性,如果属性值与"pro"相同,则注入该bean。
    @Bean("ds")
    @Profile("pro")
    public Datasource  datasource2(){
        return  new Datasource("jdbc:mysql://127.0.0.1/pro","123333","12333");
    }
}

测试

指定环境变量属性为pro。那么 @Profile("pro")标注的,则生效。

java 复制代码
public class App {
    public static void main(String[] args) {

        //创建无配置类的IOC容器
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();

        //设置对应的环境信息
        ac.getEnvironment().setActiveProfiles("pro");

        //手动注册配置类【注册后必须刷新】
        ac.register(MyConfig.class);
        ac.refresh();

        Object dev = ac.getBean("ds");
        System.out.println(dev);
    }
}

4.7 Bean的作用域

js 复制代码
	1、通过bean标签或通过@Bean注解注入的bean,默认情况下均为单例模式。即多次调用getBean(),获取的对象都是同一个对象。可通过scope进行设置。	
	
	2、scope用于设置bean的作用域。
				scope="singleton"  单例模式,默认值。
				scope="prototype"  原型模式。
	
xml 复制代码
		
	3、bean标签作用域设置:
			1)使用spring配置文件配置bean。默认为单例。
			     		 <bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean>

			2)基础设置
					设置单例模式,可省略,默认值。
     			 		<bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="singleton" ></bean>
		
					设置多例模式
     			 		<bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="prototype" ></bean>
java 复制代码
	4、@Bean注解作用域设置:
			1)使用@Bean配置bean。默认为单例。
						   @Bean("ds" )
						    public Datasource  datasource1(){
						        return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");
						    }
			
			2)基础设置
					设置单例模式
							 方式一
									 @Bean("ds" )
								     @Scope
								     public Datasource  datasource1(){
								        return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");
								     }

							方式二
									 @Bean("ds" )
								     @Scope("singleton")
								     public Datasource  datasource1(){
								        return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");
								     }

					设置多例模式
									 @Bean("ds" )
								     @Scope("prototype")
								     public Datasource  datasource1(){
								        return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");
								     }

1 基于xml配置,作用域详解

1)默认情况下为单例模式

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

      <bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean>
</beans>

测试

java 复制代码
public class AppStart {

    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");

        Car car = (Car)ac.getBean("car");
        System.out.println(car);
        Car car2 = (Car)ac.getBean("car");
        System.out.println(car2);

    }
}
2)通过scope属性设置单例作用域(默认,可省略)

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

      <bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="singleton" ></bean>
</beans>

测试

java 复制代码
public class AppStart {

    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");

        Car car = (Car)ac.getBean("car");
        System.out.println(car);
        Car car2 = (Car)ac.getBean("car");
        System.out.println(car2);

    }
}
3)通过scope属性设置多例作用域

applicationContext.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

      <bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="prototype" ></bean>
</beans>

测试

java 复制代码
public class AppStart {

    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");

        Car car = (Car)ac.getBean("car");
        System.out.println(car);
        Car car2 = (Car)ac.getBean("car");
        System.out.println(car2);

    }
}

2 基于JavaConfig配置,作用域详解

1)默认情况下为单例模式

MyConfig.java

java 复制代码
@Configuration
public class MyConfig {

    @Bean("ds" )
    public Datasource  datasource1(){
        return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");
    }

}

测试

java 复制代码
public class App {
    public static void main(String[] args) {

        //创建无配置类的IOC容器
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);

        Object dev = ac.getBean("ds");
        System.out.println(dev);

        Object dev2 = ac.getBean("ds");
        System.out.println(dev2);
    }
}
2)通过scope设置单例作用域(默认,可省略)

MyConfig.java

java 复制代码
@Configuration
public class MyConfig {

    @Bean("ds" )
    @Scope("singletone")
    public Datasource  datasource1(){
        return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");
    }

}

测试

java 复制代码
public class App {
    public static void main(String[] args) {

        //创建无配置类的IOC容器
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);

        Object dev = ac.getBean("ds");
        System.out.println(dev);

        Object dev2 = ac.getBean("ds");
        System.out.println(dev2);
    }
}
3)通过scope属性设置多例作用域

MyConfig.java

java 复制代码
@Configuration
@Configuration
public class MyConfig {

    @Bean("ds" )
    @Scope("prototype")
    public Datasource  datasource1(){
        return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");
    }

}

测试

java 复制代码
public class App {
    public static void main(String[] args) {

        //创建无配置类的IOC容器
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);

        Object dev = ac.getBean("ds");
        System.out.println(dev);

        Object dev2 = ac.getBean("ds");
        System.out.println(dev2);
    }
}
复制代码
Spring框架提供了一系列的生命周期注解,用于管理bean对象的创建、初始化和销毁过程。下面是对一些常用的生命周期注解进行详解:

@PostConstruct:该注解被标注在方法上,表示在对象创建完成并且属性注入完成后执行。通常用于执行一些初始化操作。

@PreDestroy:该注解也被标注在方法上,表示在对象销毁之前执行。通常用于执行一些资源释放的操作。

@Autowired:该注解用于自动注入依赖对象。当容器中存在多个相同类型的bean时,可以结合@Qualifier注解指定具体的bean。

@Qualifier:该注解与@Autowired注解结合使用,用于指定注入的具体bean。可以通过指定bean的名称或者自定义的限定符来确定注入的对象。

@Resource:该注解也用于自动注入依赖对象,可用于注入其他bean、属性、方法或者配置文件等。它支持根据名称进行注入,默认按照byName方式查找,如果找不到对应的bean,则按照byType方式查找。

@Value:该注解用于注入属性值,可以直接注入基本类型、字符串、数组、集合以及其他bean对象等。

@Component:该注解用于将类标识为一个组件,表示该类将由Spring容器进行管理,可通过扫描@ComponentScan注解指定的包路径进行自动扫描。

@Controller、@Service、@Repository:这些注解分别用于标识控制层、服务层和数据访问层的组件,是@Component的特殊化,用于更细粒度地描述组件的职责。

@Configuration:该注解用于标识配置类,表示该类是一个配置类,其中可能包含@Bean注解用于定义bean对象。

@Bean:该注解用于标识方法,表示将方法返回的对象注册为一个bean,可以指定bean的名称、作用域、依赖关系等。
相关推荐
一只叫煤球的猫2 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
bobz9652 小时前
tcp/ip 中的多路复用
后端
bobz9652 小时前
tls ingress 简单记录
后端
皮皮林5513 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
你的人类朋友4 小时前
什么是OpenSSL
后端·安全·程序员
bobz9654 小时前
mcp 直接操作浏览器
后端
前端小张同学6 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook6 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康7 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在7 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net