Spring2.4——FactoryBean、获取Bean的id

1、FactoryBean——Spring提供的一个特殊接口

     FactoryBean接口是工厂Bean的标准接口,实现该接口的Bean通常作为工厂Bean使用,
     当我们把工厂Bean部署在容器中、并通过getBean()方法来获取时,容器返回的不是FactoryBean实例,而是返回FactoryBean的产品(也就是该工厂Bean的getObject方法的返回值)。

       实现FactoryBean接口要实现3个方法

       -  Object getObject():该方法负责返回工厂的产品。
       -  getObjectType() :该方法返回产品的类型。
       -  isSingleton():该方法返回产品是否为单例。

eg:

实现FactoryBean接口获取任意类的、任意静态field的值

(1)GetFieldFactoryBean.java

public class GetFieldFactoryBean implements FactoryBean<Object>{

	private String className;
	private String targetField;
	
	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String getTargetField() {
		return targetField;
	}

	public void setTargetField(String targetField) {
		this.targetField = targetField;
	}

	@Override
	public Object getObject() throws Exception {
		//获取任意类的、任意静态field的值。
		Class clazz = Class.forName(className);
		Field field = clazz.getField(targetField);
		// Field是静态的,不需要用对象即可获取值
		return field.get(null);
	}

	// 多余的
	@Override
	public Class<?> getObjectType() {
		return Object.class;
	}

	@Override
	public boolean isSingleton() {
		return false;
	}

}

Dinasaur.java

public class Dinosaur  implements Dog{

	//如果需要通过FactoryBean获取静态field的值,也需要提供get和set方法
	public static int flag = 1; 
	public static int getFlag() {
		return flag;
	}
	public static void setFlag(int flag) {
		Dinosaur.flag = flag;
	}
}
(2)beans.xml

<bean id="getField" class="cony.factory.GetFieldFactoryBean"
	abstract="true"
/>

<bean id="val1" parent="getField"
p:className="cony.domain.Dinosaur"
p:targetField="flag"
/>

<bean id="val2" parent="getField"
p:className="java.sql.Connection"
p:targetField="TRANSACTION_SERIALIZABLE"
/>

(3)测试

		ApplicationContext appContext = new ClassPathXmlApplicationContext("beans.xml");
		System.out.println(appContext.getBean("val1"));
		System.out.println(appContext.getBean("val2"));
测试结果:



2、 获取Bean的id

需要让Bean实现BeanNameAware接口以及实现该接口中setBeanName()方法。
eg:

(1)Puppy.java

public class Puppy implements ApplicationContextAware,BeanNameAware{

	String kind;
	private int age;
	private ApplicationContext ctx;
	private String beanId;

	public void bark(){
		System.out.println("提前获取的id: "+beanId);
		System.out.println(ctx.getMessage("bark", null,Locale.getDefault(Category.FORMAT)));
	}
	@Override
	public void setBeanName(String beanId) {
		System.out.println("调用setBeanName方法");
		this.beanId = beanId;	
	}
	@Override
	public void setApplicationContext(ApplicationContext ctx)
			throws BeansException {
		System.out.println("调用setApplicationContext方法");
		this.ctx = ctx;	
	}	public String getKind() {	
		return kind;
	}
//setter、getter...
} 
(2)beans.xml

	<bean id="messageSource"
		class="org.springframework.context.support.ResourceBundleMessageSource">
		<property name="basenames">
			<list>
				<value>mess</value>
			</list>
		</property>
	</bean>
	
	<bean id="puppy"
	class="cony.domain.Puppy"
	p:kind="牧羊犬"
	p:age="9"
	/>

(3)测试

		ApplicationContext appContext = new ClassPathXmlApplicationContext("beans.xml");
		Puppy puppy = appContext.getBean("puppy",Puppy.class);
		puppy.bark();
		System.out.println();
测试结果:可以看出setBeanName方法先于setApplicationContext方法被调用


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值