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

1、
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接口。

你可能感兴趣的:(FactoryBean)