一、什么是Bean
Bean是注册到Spring容器中的Java类,控制反转和依赖注入都是通过Bean实现的,任何一个Java类都可以是一个Bean。Bean由Spring进行管理,可以通过xml文件对bean进行配置和管理。
二、BeanFactory接口和ApplicationContext接口;
Spring提供了几个BeanFactory接口的实现类,其中最常用的是XmlBeanFactory,它可以读取XML文件并根据XML文件中的配置信息生成BeanFactory接口的实例,BeanFactory接口的实例用于管理Bean。XmlBeanFactory类读取XML文件生成BeanFactory接口实例的具体语法格式:
在测试代码中:
XML
BeanFactory beanFactory=new XmlBeanFactory(new FileSystemResource("bean.xml"));
ApplicationContext接口建立在BeanFactory接口的基础之上,它丰富了BeanFactory接口的特性,例如,添加了对国际化、资源访问、事件传播等方面的支持。
ApplicationContext接口可以为单例的Bean实行预初始化,并根据<property>元素执行setter方法,单例的Bean可以直接使用,提升了程序获取Bean实例的性能。
ApplicationContext接口的常用实现类:
在测试代码中:
java
// 如加载applicationBean1.xml配置
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationBean1.xml");
然后再 通过创建的容器对象获取配置中bean1的实例
如: Bean1 bean=(Bean1) applicationContext.getBean("bean1");
三、Bean的两种配置方式
Spring容器支持XML和Properties两种格式的配置文件,在实际开发中,最常用的是XML格式的配置文件。++XML是标准的数据传输和存储格式,方便查看和操作数据++ 。在Spring中,XML配置文件的根元素是<beans>,<beans>元素包含<bean>子元素,每个<bean>子元素可以定义一个Bean,通过<bean>元素将Bean注册到Spring容器中。
普通的Bean通常只需定义id(或者name)和class两个属性
<bean>元素的常用属性:
|---------------------|---------------------------------------------------------------------------------------------------|
| 元素 | 描述 |
| <constructor-arg> | 使用**<constructor-arg>元素**可以为Bean的属性指定值。使用构造方法注入时 |
| <property> | <property> 元素的作用是调用Bean实例中的setter方法完成属性赋值,从而完成依赖注入。属性setter方法在bean中注入时使用 |
| ref | ref 是<property>、<constructor-arg>等元素的属性,可用于指定Bean工厂中某个Bean实例的引用;也可用于指定Bean工厂中某个Bean实例的引用。 |
| value | value 是<property>、<constructor-arg>等元素的属性,用于直接指定一个常量值;也可以用于直接指定一个常量值。 |
| <list> | <list> 元素是<property>等元素的子元素,用于指定Bean的属性类型为List或数组。 |
| <set> | <set> 元素是<property>等元素的子元素,用于指定Bean的属性类型为set。 |
| <map> | <map> 元素是<property>等元素的子元素,用于指定Bean的属性类型为Map。 |
| <entry> | <entry> 元素是<map>元素的子元素,用于设定一个键值对。<entry>元素的key属性指定字符串类型的键。 |
四、Bean 的实例化:
在学习静态工厂实例化、实例工厂方式实例化前先了解什么是工厂模式
**工厂模式:**工厂提供服务(方法),客户只需要满足服务的条件即可,解耦很明显,这里自己的责任自己负责,每一环没有必要关心另一环的逻辑实现。
什么是工厂: (针对接口编程,不针对实现编程):用于封装创建对象的代码,负责处理创建对象的细节的类被称为工厂(Factory)
**使用工厂模式的优点:**将创建对象的代码集中在一个对象或方法中,避免代码中的重复,便于以后的维护
静态工厂和实例工厂区别: 静态工厂指的是工厂的服务是静态的,也就是工厂提供的方法是static的,那么这些方法仅有工厂提供以及管理更新等,跟客户端或者说调用端是没有关系的;实例工厂指的是工厂提供的方法服务室非static的,那么客户端或者调用端是需要自己创建工厂对象然后去调用工厂中的方法或者服务的,那么管理这些方法或者服务相当于是客户端了。所以静态工厂和实例工厂主要是实际参与管理工厂管理者的不同,其次实例工厂设计相对灵活,客户端与工厂都可以参与管理设计,静态工厂相对正式死板
- 静态工厂方法:工厂初始化之前,工厂中的类已经被实例化放在工厂容器中,直接调用静态方法可以返回Bean的实例
- 实例工厂方法:工厂在构造方法初始化时,会将类进行实例化放在工厂中,即调用工厂本身,再调用工厂的实例方法来返回bean实例
构造器实例化(默认)、静态工厂实例化、实例工厂方式实例化。
构造器实例化:
xml 配置文件:
id唯一,calss指定Bean具体实现类,必须是完整的类名,可以在Bean1.java文件中右击"public class Bean1"中的Bean1,选中Copy Qualifiel Name得到。注意这里用"."分隔。
静态工厂实例化: (比 构造器实例化 多一个静态工厂类)
xml 配置文件:
id唯一,class为工厂方法类,factory-method值为方法名,确定使用了工厂中的哪个方法。
静态工厂类:
静态方法返回一个Bean2对象。
实例工厂实例化:
xml 配置文件:
两个bean第一个为静态工厂,class为静态工厂类。第二个为bean3,factory-bean属性配置实例工厂,factory-method确定使用工厂中哪个方法。
工厂类:
返回一个Bean3对象。
三种方法区别:
五、基于XML的两种装配方式(详见Spring学习(二)笔记)
基于XML的装配就是读取XML配置文件中的信息完成依赖注入,Spring容器提供了两种基于XML的装配方式,属性setter方法注入和构造方法注入,我们在Spring学习(二)的笔记中有介绍
注意:
属性setter方法注入要求一个Bean必须满足以下两点要求。
(1)Bean类必须提供一个默认的无参构造方法。
(2)Bean类必须为需要注入的属性提供对应的setter方法。
使用构造方法注入时,在配置文件里,需要使用<bean>元素的子元素<constructor-arg>来定义构造方法的参数,例如,可以使用其value属性(或子元素)来设置该参数的值。
六、基于注解的装配
装配就是给Spring的对象赋值,注解方式是最常见的方式
1、在pom.xml中添加注解所需要的依赖
XML
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
2、在applicationContext.xml文件中引入Context约束并启动Bean的自动扫描功能。
XML
<!-- 使用context命名空间,在配置文件中开启相应的注解处理器 -->
<context:component-scan base-package="com.itheima" />
3、Spring的常用注解
对象创建用到的注解
@Component用于非三层(在pojo类中使用)
@Controller用于web控制层
@Service用于service业务逻辑层
@Repository用于Dao数据访问层
可以跨层使用,混用不会报错但是不符合企业开发的规范
依赖注入用到的注解
@Value给基本属性赋值例如:
@Value("1")
private int id;
@Value("张三")
private String name;
@Value("123")
private String password;
@Resource通过name属性指向bean的唯一标识进行赋值,例如:
//使用@Resource注解注入UserDao,name的值看@Repository注解的赋值
写法:@Resource(name="userDao")
private UserDao userDao;
@Autowired不需要指向任何标识根据类型自动注入进行赋值(自动装配用的最多)
@Qualifier指定要自动装配的对象名称,通常与@Autowired联合使用
在Bean的作用域中使用的注解
@Scope指定Bean实例的作用域(通常有两个属性,单例与多例默认为前者,在pojo类中使用)如:@Scope("singleton")
在Bean的生命周期中常使用的注解
@PostConstruct指定Bean实例完成初始化后调用的方法。
@PreDestroy指定Bean实例销毁前调用的方法。
七、Bean的生命周期
Bean的生命周期是指Bean实例被创建、初始化和销毁的过程。在Bean的两种作用域singleton和prototype中,Spring容器对Bean的生命周期的管理是不同的。在singleton作用域中,Spring容器可以管理Bean的生命周期,控制着Bean的创建、初始化和销毁。在prototype作用域中,Spring容器只负责创建Bean实例,不会管理其生命周期。
两个时间节点:Bean实例初始化后和Bean实例销毁前
监控两个节点的方式:一种是使用XML配置文件,一种是使用注解,我们学习基于注解的方式
在pojo类中:
@PostConstruct
public void init(){System.out.println("Bean的初始化完成,调用init()方法"); }
@PreDestroy
public void destroy(){System.out.println("Bean销毁前调用destroy()方法");
在测试中:
//初始化自动完成
//销毁Spring容器中的所有Bean
AbstractApplicationContext ac=(AbstractApplicationContext)
applicationContext;
ac.registerShutdownHook();
八、总结
1、首先介绍了Spring IoC容器,包括BeanFactory接口和ApplicationContext接口;
2、其次介绍了Bean的两种配置方式:支持XML和Properties,介绍了xml配置中XML配置文件的根元素<beans>中<bean>子元素的常用属性;
3、接着学习了Bean 的3种实例化方法,包括构造方法实例化、静态工厂实例化和实例工厂实例化;
4、然后学习了Bean的作用域,包括singleton作用域和prototype作用域;
5、接着学习了Bean的3种装配(即赋值)方式,包括基于XML的装配、基于注解的装配和自动装配,
6、最后学习了Bean的生命周期。