1.容器工厂bean:
这个工厂模式相对于前面的实例工厂模式、静态工厂模式有所区别,因为前面是标准的工厂模式,调用工厂方法来产生bean,而容器工厂bean是实现了, FactoryBean,来产生bean,当调用工厂的getBean的时候容器不会获取FactoryBean的实例而是获取Factory的产品;
FactoryBean在Spring中是一个很重要的接口,实例工厂模式和静态工厂模式,返回的是工厂的实例,而实现了FactoryBean的类等到的是Factory的产品,它不会产生Factory的实例。
例如:
//定义了一个People类
public interface People {
public String sayHello(String name);
public String sayGoodBye(String name);
}
//定义了一个American
public class American implements People{
public String sayHello(String name) {
// TODO Auto-generated method stub
return name+",hello";
}
public String sayGoodBye(String name) {
// TODO Auto-generated method stub
return name+",goodbye";
}
}
//定义了一个Chiner类
public class Chiner implements People{
public String sayHello(String name) {
// TODO Auto-generated method stub
return name+",你好";
}
public String sayGoodBye(String name) {
// TODO Auto-generated method stub
return name+",再见";
}
}
//people Factory工厂
public class PeopleFactory implements FactoryBean<People> {
People people=null;
public People getObject() throws Exception {
if (people==null) {
people=new American();
}
return people;
}
public Class<? extends People> getObjectType() {
// TODO Auto-generated method stub
return American.class;
}
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;
}
}
//定义bean.xml
<bean id="chiner" class="factory.PeopleFactory"/>
//测试
ApplicationContext ctx=new ClassPathXmlApplicationContext("/bean/bean.xml"); //初始化所有的bean里面的xml文件
People people1=ctx.getBean("chiner",People.class);
System.out.println(people1.sayGoodBye("guyan"));
System.out.println(people1.sayHello("guyan"));
People people2=ctx.getBean("chiner",People.class);
System.out.println(people1==people2);//true,因为工厂产生的bean是单例所以共享一个实例
2.强制初始化Bean:
depends-on:在初始化主调bean之前,同时强制初始化一个或多个bean
3.bean的生命周期:
(1) 依赖注入之后:
使用init-method:
使用这种方式不需要将Spring的接口耦合在一起
initializingBean:
要实现initializingBean这个接口,同时实现afterPropertiesSet()这个方法
例如:
<bean id="chinese" class="serviceImpl.Chinese" init-method="test">
<property name="axe" ref="steelAxe"/>
</bean>
完成依赖注入之后 spring会自动检测是否有实现了生命接口,如果有的话就会先执行afterPropertiesSet这个方法 然后执行init-method的这个方法
(2)Bean销毁之前的行为:
使用destory-method:
使用这种方式不需要将Spring的接口耦合在一起;
DisposableBean:
要实现DisposableBean这个接口,同时实现destory()这个方法
例如:
<bean id="chinese" class="serviceImpl.Chinese" destory-method="close">
<property name="axe" ref="steelAxe"/>
</bean>
在销毁bean之前spring就会自动检测有没有实现了DisposableBean这个接口,如果有的话就会先执行destory()这个方法然后执行destory-method=“close”这个方法
怎么保证手动优雅的关闭spring容器那,使用
ApplicationContext ctx=new ClassPathXmlApplicationContext("/bean/bean.xml"); //初始化所有的bean里面的xml文件
ctx.registerShutDownHook //需要在jvm注册一个钩子然后关闭jvm的钩子
关闭完spring容器之后,spring会自动调用销毁的方法;
4.协调作用域不同步的bean:
什么叫协调作用域不同步的bean,当我们初始化的spring容器的时候,默认初始化的是单例的,每当我们获取实例的时候都是同一个对象,如果我们在主调里面注入一个原形模式的bean。
怎么做才能做到,当我们每次获取单例的实例之后,同时获取一个新的原型模式的实例,这样才会同步:
例如:
public class SteelAxe implements Axe {
public SteelAxe(){
System.out.println("Spring 实例化依赖Bean:SteelAxe的实例");
}
public String chop() {
return "钢斧砍柴真快";
}
}
//定义一个抽象类
public abstract class Chinese implements Person {
private Axe axe;
public void setAxe(Axe axe) {
System.out.println("spring 执行依赖注入");
this.axe = axe;
}
public Chinese(){
System.out.println("Spring 实例化依赖Bean:Chinese的实例");
}
public abstract Axe getAxe();
public void useAxe() {
System.out.println(axe.chop());
}
}
<bean id="steelAxe" class="serviceImpl.SteelAxe"/>
<bean id="chinese" class="serviceImpl.Chinese" >
<lookup-method name="getAxe" bean="steelAxe"/>
</bean>
lookup-method 每次调用getAxe 都会返回steelAxe的实例,spring 帮助 Chinese 这个抽象类进行实例化
当调用getAxe这个方法的时候
public Axe getAxe(){
。。。。//初始化spring容器
return ctx.getBean("steelAxe");
}