一、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 分钟前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
荆州克莱4 分钟前
springcloud整合nacos、sentinal、springcloud-gateway,springboot security、oauth2总结
spring boot·spring·spring cloud·css3·技术
serve the people6 分钟前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端
qmx_071 小时前
HTB-Jerry(tomcat war文件、msfvenom)
java·web安全·网络安全·tomcat
为风而战1 小时前
IIS+Ngnix+Tomcat 部署网站 用IIS实现反向代理
java·tomcat
技术无疆3 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
罗政6 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
架构文摘JGWZ6 小时前
Java 23 的12 个新特性!!
java·开发语言·学习
拾光师7 小时前
spring获取当前request
java·后端·spring
aPurpleBerry7 小时前
neo4j安装启动教程+对应的jdk配置
java·neo4j