1、bean的实例化方式
bean(类对象)的实例化方式:
①.构造器实例化(无参数构造器,与构造器的访问权限无关),最标准,使用最多。
②.静态工厂方法实例化:解决系统遗留问题(了解)
③.实例工厂方法实例化:解决系统遗留问题(了解)
④.实现FactoryBean接口实例化:实例工厂变种:集成其他框架使用:SqlSessionFactoryBean
这里重点介绍第一种和第四种方式!
1.1 构造器实例化
(1)导入依赖
(2)创建类
(3)新建spring配置文件,并且添加bean标签,通过反射,将类的加载,创建对象等等操作交给spring完成。
前三步具体代码可参考spring配置
(4)测试
@Test
/*推荐使用--》ApplicationContext,
特点:在创建容器对象的时候,就会实例化容器管理的对象(需要更多依赖,context等);*/
public void run2(){
ClassPathXmlApplicationContext Context = new ClassPathXmlApplicationContext("com/project/test01/bean/User.xml");
User user = Context.getBean("user", User.class);
System.out.println(user);
}
1.2 静态工厂实例化
1.3 动态工厂实例化
1.4 实现FactoryBean接口实例化
(1)导入依赖
(2)新建一个工厂类,该类需要实现FactoryBean接口,并实现getObject,getObjectType方法。
Spring创建出的对象就是工程类getObject()方法返回的对象类型
public class EmpFactory implements FactoryBean<Emp> {
@Override
public Emp getObject() throws Exception {
System.out.println("工程类启动,返回emp对象");
return new Emp();
}
@Override
public Class<?> getObjectType() {
return null;
}
}
(3)新建普通类Emp
(4)新建Spring配置文件
这里要添加的是工厂类的对象
<?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 id="empfactory" class="com.project.test01.bean.EmpFactory"/>
</beans>
(5)获取工厂类实例化对象Emp
/*FactoryBean接口实例化*/
/*创建一个工厂类,该类实现了FactoryBean接口,spring框架会自动判断工程类是否实现了factoryBean接口,
spring创建出的对象就是工程类getObject()方法返回的对象类型*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/project/test01/bean/EmpFactory.xml")
public class SpringTest_Emp {
@Autowired
private ApplicationContext b;
@Test
public void run(){
Emp empfactory = b.getBean("empfactory", Emp.class);
empfactory.say();
}
}
只需要修改工厂类的getObject方法中的返回值,就可以不断的获取到新类的bean对象。
2、bean的作用域
bean的作用域:指的是一个bean对象可以存活多久,通过bean元素的scope属性来指定.
<bean id="" class="" scope="作用域"/>
(1)singleton: 单例 ,在Spring IoC容器中仅存在一个Bean实例 (默认的scope)
(2)prototype: 多例 ,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时 ,相当于执行new XxxBean():不会在容器启动时创建对象
(3)request: 用于web开发,将Bean放入request范围 ,request.setAttribute(“xxx”) , 在同一个request 获得同一个Bean
(4)session: 用于web开发,将Bean 放入Session范围,在同一个Session 获得同一个Bean
(5)globalSession: 一般用于Porlet应用环境 , 分布式系统存在全局session概念(单点登录),如果不是porlet环境,globalSession 等同于Session
在开发中主要使用 scope=“singleton”、 scope=“prototype”
对于Struts2中的Action使用prototype类型,其他使用singleton
3、bean的生命周期
比如DataSource,SqlSessionFactory最终都需要关闭资源:在Bean销毁之前,都要调用close方法.
<bean id="someBean" class="......" init-method="该类中初始化方法名" destroy-method="该类中销毁方法名">
</bean>
init-method:bean生命周期初始化方法,对象创建后就进行调用
destroy-method:容器被销毁的时候,如果bean被容器管理,会调用该方法。
default-init-method,default-destroy-method.配置文件中所有的bean元素的初始化方法和销毁方法
分析原理:
如果bean的scope=“prototype”,那么容器只负责创建和初始化,销毁方法它并不会被spring容器管理。交给用户自己调用.
当bean的scope="prototype"时,Spring容器在启动时,并不会将创建出来的对象放在容器当中.而是在每次获取对象时,都来创建一个新的对象.因此,在容器销毁的时候,并不知道要销毁该对象.因此就不会调用对象的销毁方法.
public class User {
private String name;
private String address;
public void say()
{
System.out.println("HelloWord!");
}
public void init()
{
System.out.println("初始化!");
}
public void destroy()
{
System.out.println("销毁了!");
}
}
<!--
初始化:init-method="" 执行实体类自定义init方法
销毁:destory-method="" 执行实体类自定义destory方法(注意:多例模式不会自动调用销毁方法,需要手动清理)
-->
<bean id="user" class="com.project.test01.bean.User" scope="singleton"
init-method="init" destroy-method="destroy">
</bean>