spring 第4天bean继承,init,destory-method

[size=large][b]深入理解Spring容器中的bean[/b][/size]
[b]使用抽象bean[/b]

1.抽象bean被作为一种模板,在spring中被应用,在ApplicationContext初始化的时候,不会初始化抽象bean, 因此抽象bean的配置中可以没有 class.
2.抽象bean的作用主要是为了减少配置文件中多个bean之间拥有的重复的配置.
3.子bean无法从父bean中继承如下属性:depends-on,autowire,singleton,scope,lazy-init
4.如果 父bean写了class 则 子bean可以不用写class 和父类共用同一个实现类.
5.如果 父bean没有写class,则子bean必须写class
6.如果 父bean写了class,子bean也写了class,子bean覆盖 父bean的属性


<!-- 抽象bean -->
<bean id="personTemplate" class="cn.sh.springmvc_java.Chinese" abstract="true">
<property name="axe" ref="stoneAxe_sf"/>
</bean>
<bean id="personTemplate1" abstract="true">
<property name="axe" ref="steelAxe_sf"/>
</bean>

<!-- 子bean继承 -->
<bean id="china_child" parent="personTemplate"/>

<!-- 子bean 覆盖父类的bean -->
<bean id="china_child1" parent="personTemplate">
<property name="axe" ref="steelAxe_sf"/>
</bean>

spring的bean继承和java中继承完全不一样

1.spring中子bean和父bean可以是不同的类型,但java中继承可以保证子类是一种特殊的父类
2.spring中的bean的继承是实例之间的关系,因此主要表现为参数的延续;而java中的继承是类之间的关系,主要表现在方法和属性的延续
3.spring中子bean不可以作为父bean使用,不具备多态性,java中的子类实例完全可以当成父类实例使用


[b]容器中的工厂bean:[/b]
1和前面介绍的静态工厂创建bean和实例工厂创建bean有区别,这里的工厂bean是spring中一种特殊的bean,该工厂bean必须实现FactoryBean接口,而且实现后的bean
只能作为工厂bean使用.
2.而且通过getBean()来获取工厂bean的时候返回的不是FactoyBean,而是工厂bean生产的java
实例
3.如果要获取 factoryBean 要在bean的id 前面加上 "&"


package cn.sh.springmvc_java.factory;

import org.springframework.beans.factory.FactoryBean;

import cn.sh.springmvc_java.American;
import cn.sh.springmvc_java.People;

/**
* 采用 spring的工厂bean:默认 是singleton
*
*/
public class PeopleFactory1 implements FactoryBean<People>{

//People p=null;
//这个方法只调用一次, 因为 scope="singleton" 如果prototype 就会每次调用
@Override
public People getObject() throws Exception {
/* // TODO Auto-generated method stub
if(p==null){
p=new American();
}*/
System.out.println("1");
return new American();
}

@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return American.class;
}

@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;
}

}



<!--可以去掉prototye 属性,这样 就是默认的单例了-->
<bean id="people" class="cn.sh.springmvc_java.factory.PeopleFactory1" scope="prototype"/>



/**
*测试 采用 factoryBean 创建的对象 发现获取不了配置ID
* xml创建的对象 可以获取配置时候的id
*/
@Test
public void test13(){
ApplicationContext act=new ClassPathXmlApplicationContext("classpath*:applicationContent.xml");
People p=act.getBean("people",People.class);
System.out.println(p.sayHello("Mary"));
System.out.println(p.sayGoodBye("Mary"));
People p1=act.getBean("people",People.class);
System.out.println(p==p1); //单例就为true 否则为false

//获取 factoryBean 本身
System.out.println(act.getBean("&people"));
System.out.println(p.getClass());
p.toString();

People pa=act.getBean("american",People.class);
System.out.println(pa.sayHello("Mary"));
System.out.println(pa.sayGoodBye("Mary"));
pa.toString(); //会打印出 配置的id
}


[b]获取bean在配置文件中ID[/b]
实现BeanNameAware 的setBeanName(String name);



package cn.sh.springmvc_java;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**
* BeanNameAware 实现后,可以获取该bean的定义时的id
* InitializingBean 实现后,可以在 spring初始化Bean完成后,执行指定的方法
* DisposableBean :Bean在被销毁前,执行特点的方法
*
* 注意: DisposableBean的 destory 方法 和 配置文件中的destory-method 只对scope的 singleton Bean有用
* 可以将 Beans 的 default-init-method 和 default-destory-method和Bean的 方法 联合起来用
*/
public class American implements People,BeanNameAware,InitializingBean,DisposableBean {

private String beanName;

@Override
public void setBeanName(String name) {
// TODO Auto-generated method stub
System.out.println("执行BeanNameAware 的set方法 获取BeanName");
this.beanName=name;
}

@Override
public String sayHello(String name) {
// TODO Auto-generated method stub
return name+",hello";
}

@Override
public String sayGoodBye(String name) {
// TODO Auto-generated method stub
return name+",Good Bye";
}

@Override
public String toString() {
// TODO Auto-generated method stub
System.out.println("china实现类,部署该Bean是指定的ID为:"+beanName);
return null;
}

//实现InitializingBean后,可以在初始化完成后 调用下面的方法 这样有代码污染
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("正在执行InitializingBean接口的afterPropertiesSet");
}

//在配置文件中配置 init-method 这种没有代码污染 推荐
public void init(){
System.out.println("init-method:正在初始化....");
}

@Override
public void destroy() throws Exception {
System.out.println("实现DisposableBean,即将被销毁...");
}

public void close(){
System.out.println("destory-method:即将被销毁.....");

}

public String getBeanName() {
return beanName;
}

}

[b]容器中bean的生命周期[/b]
1.spring可以管理singleton 作用域的bean的生命周期,spring可以精确的知道该bean何时被创建,何时初始化完成,容器何时销毁该bean.
2.对于prototype的bean.spring只负责创建,之后,完全交割客户端代码,容器不在跟踪其生命周期.

依赖关系注入之后的行为 spring提供了两种方式完成
1.使用init-mehtod
2.实现initializingBean 接口
3.如果这两个都写了, 会先执行 initialingBean 接口的方法 然后执行 init-method

Bean销毁之前的行为
1.使用 destory-method
2.实现despoableBean接口


<bean id="peopleFactory" class="cn.sh.springmvc_java.factory.PeopleFactory"/>
<bean id="china" factory-bean="peopleFactory" factory-method="getPeople">
<constructor-arg value="chin"/>
</bean>
<bean id="american" factory-bean="peopleFactory" factory-method="getPeople" scope="prototype" init-method="init" destroy-method="close">
<constructor-arg value="ame"/>
</bean>


//测试init -method 和 destory -method
@Test
public void test15(){
AbstractApplicationContext act=new ClassPathXmlApplicationContext("classpath*:applicationContent.xml");
People pa=act.getBean("american",People.class);
pa.toString();
//未来让spring容器注册关闭钩子
act.registerShutdownHook();
System.out.println("aaa");
pa=null;
System.gc();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值