Spring Bean相关的接口、aware接口、FactoryBean

1、
Java代码  收藏代码
package spring.beansandcontext; 
 
import org.springframework.beans.BeansException; 
import org.springframework.beans.factory.BeanClassLoaderAware; 
import org.springframework.beans.factory.BeanFactory; 
import org.springframework.beans.factory.BeanFactoryAware; 
import org.springframework.beans.factory.BeanNameAware; 
import org.springframework.beans.factory.DisposableBean; 
import org.springframework.beans.factory.InitializingBean; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.ApplicationContextAware; 
 
//如果被装配的Bean实现了相应的接口,就可以在Bean中获得相应的信息。,或者进行某些操作。 
public class HelloServiceImpl implements HelloService, 
//以下同时为接口的调用的顺序 
BeanNameAware,//获得Bean名,也就是<Bean>标签的id属性值。 
BeanClassLoaderAware,//获得装载过程中的ClassLoader对象。 
BeanFactoryAware,//获得BeanFactory对象 
ApplicationContextAware,//获得ApplicationContext对象 
 
InitializingBean, //在Bean的所有属性设置完后,并且在调用完上面接口的方法后,调用此接口的afterPropertiesSet方法 
DisposableBean //当销毁Bean时,调用此接口的destroy方法 

    private String greeting; 
 
    public String getGreeting() { 
        // TODO Auto-generated method stub 
        return "hello " + greeting; 
    } 
 
    // 以下同时为方法的调用的顺序 
    public void setGreeting(String greeting) { 
        this.greeting = greeting; 
        System.out.println("setGreeting 设置greeting属性值"); 
    } 
 
    public void setBeanName(String name) { 
        System.out.println("BeanNameAware 接口方法  获得Bean名,也就是<Bean>标签的id属性值:" + name); 
    } 
 
    public void setBeanClassLoader(ClassLoader arg0) { 
        System.out.println("BeanClassLoaderAware接口方法 获得装载过程中的ClassLoader对象:" + arg0); 
    } 
 
    public void setBeanFactory(BeanFactory arg0) throws BeansException { 
        System.out.println("BeanFactoryAware接口方法 获得BeanFactory对象:" + arg0); 
    } 
 
    public void setApplicationContext(ApplicationContext applicationContext) 
            throws BeansException { 
        System.out.println("ApplicationContextAware接口方法 获得ApplicationContext对象:" + applicationContext); 
    } 
 
    public void afterPropertiesSet() throws Exception { 
        System.out.println("InitializingBean接口方法 afterPropertiesSet"); 
 
    } 
    public void initMethod() { 
        System.out.println("<bean>标签的init-Method属性指定的方法,此方法在afterPropertiesSet()之后调用"); 
    } 
 
    public void destroy() throws Exception { 
        System.out.println("DisposableBean 接口方法 destroy"); 
    } 
 
    public void destroyMethod() { 
        System.out.println("<bean>标签的destroy-Method属性指定的方法,此方法在destroy()之后调用"); 
    } 


2、Spring的InitializingBean和init-method


Spring的InitializingBean和init-method
Spring在设置完一个bean所有的属性后,会检查bean是否实现了InitializingBean接口,如果实现就调用bean的afterPropertiesSet方法。另外,如果bean是单例的,则afterPropertiesSet方法只会被调用一次;否则每次创建bean时afterPropertiesSet方法都会被重新调用.
Spring虽然可以通过InitializingBean完成一个bean初始化后对这个bean的回调,但是这种方式要求bean实现 InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起了。通常情况下不建议直接实现InitializingBean,而是用Spring提供的init-method的功能来执行一个bean 子定义的初始化方法,这可以在一个bean的配置文件中通过init-method声明:
<bean id="testBean" class="TestClass" init-method="initialize"/>

spring要求这个init-method方法是一个无参数的方法
如果一个bean同时实现了这两种方式的初始化配置,则spring会先调用afterPropertiesSet方法,然后通过反射调用init-method,任何一个方法出错都会导致spring创建bean失败.如果afterPropertiesSet方法调用失败,也不会再继续执行init-mehtod方法.


init-method属性用于指定自定义初始化方法

---------------------------------

引用配置文件的值
<!-- cache.properties中定义memcache.cache_prefix=sns\:2\: -->
<bean id="globalCacheManager" class="com.xiaonei.wap.framework.cache.GlobalCacheManager">
<property name="memCacheManager" ref="memCacheManger" />
<property name="cachePrefix" value="${memcache.cache_prefix}" />
</bean>

spring提供了很多*aware接口,比较常用的就是BeanFactoryAware,ApplicationContextAware,BeanNameAware
实现这些接口的Bean则能获得相应的BeanFactory,ApplicationContext实例,从而能直接获得容器信息。

3、FactoryBean接口作用就是封装自己定制的实例化逻辑(例如你想用工厂模式来实例化,或者Class.getInstance()),然后让spring统一管理。
http://fuhuijun.iteye.com/blog/1260609
http://readwall.blog.163.com/blog/static/10127132201042751036331
FactoryBean 用于在 spring 容器中创建其他的 Bean, 我们平时用得最多的 JndiObjectFactoryBean, hibernate 的 LocalSessionFactoryBean 都是 FactoryBean 的具体实现, 既然如此, 读取动态配置就变得易如反掌了, 假如我们要实现动态读取数据库配置的功能, 拿使用率最高的 BasicDatasource 为例, 简单的实现一个 BasicDatasource FactoryBean 如下即可

  代码

public class BasicDataSourceFactoryBean implements FactoryBean {
 public Object getObject() throws Exception {
  BasicDataSource dataSource = new BasicDataSource();
  // 读取外部配置, 设置到 dataSource 中 ...
  return dataSource;
 }

 public Class getObjectType() {
  return BasicDataSource.class;
 }

 public boolean isSingleton() {
  return true;
 }
}

然后在 spring 中如此声明

<bean id="dataSource" class="BasicDataSourceFactoryBean ">
... 你的配置来源
</bean>
4、BeanPostProcessor,BeanFactoryPostProcessor接口都是容器扩展点,容许spring在bean初始化或者销毁的时候回调,回调顺序可以用order来指定,前提是必须执行Ordered接口。

猜你喜欢

转载自qi20088.iteye.com/blog/2231379