Spring进阶之路(6)-抽象Bean与工厂Bean以及获取Bean的id

本文介绍Spring框架中如何使用抽象Bean简化配置,并通过工厂Bean实现更灵活的实例化过程。此外还展示了如何利用BeanNameAware接口获取Bean的ID。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有的时候我们一些类中的参数有一部分是重复的,如果不管这些重复的参数的话,会导致配置文件比较臃肿,尤其是当这些参数比较多而且被很多的bean用到的时候。那么最好的方式是这样的,将这些重复的东西抽取出来放在一个公共的模块中,那么我需要的时候,直接引用就可以了,就如同java中类的继承,可以将相同的部分放在一个公共的模块里即可。


抽象Bean


下面看一个实例:

package com.siti.spring20160305;

public interface Person {

	void printName();
	
}
WangYang这个类实现了Person这个接口

package com.siti.spring20160305;

public class WangYang implements Person{

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public void printName() {
		System.out.println("My name is wangyang!" + this.name);
	}
	
}

类似的WY类也实现了这个接口

package com.siti.spring20160305;

public class WY implements Person{

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public void printName() {
		System.out.println("My name is wy!" + this.name);
	}
	
	
}

在配置文件中,设置为抽象Bean,即abstract="true",这样在进行引用的时候,引用父Bean的信息,就用parent="*****"。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- 
		普通的情况下我们会这样配置:在每个bean中直接配置参数,如果说像下面两个bean来说有一部分重复了,
		那么可以直接拿出来作为抽象的bean,然后让下面两个bean引用即可,这样的好处就是使得配置文件不至于臃肿,
		提高可维护性。
	 -->
	<!--  
	<bean name = "wangyang" class = "com.siti.spring20160305.WangYang">
		<property name="name" value="> wangyang"></property>
	</bean>
	<bean name = "wy" class = "com.siti.spring20160305.WY">
		<property name="name" value="> wy"></property>
	</bean>
	 -->
	 
	 <bean id = "commonProperty" abstract="true">
	 	<property name="name" value="> commonProperty"></property>
	 </bean>
	 
	<bean name = "wangyang" class = "com.siti.spring20160305.WangYang" parent="commonProperty">
	</bean>
	<bean name = "wy" class = "com.siti.spring20160305.WY" parent="commonProperty">
	</bean>
	
</beans>

测试代码

package com.siti.spring20160305;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext20160305.xml");
		Person wangyang = context.getBean("wangyang", Person.class);
		wangyang.printName();
		
		Person wy = context.getBean("wy", Person.class);
		wy.printName();
	}

}


工厂Bean


在前面的博客中提到过工厂,但是之前的工厂是工厂模式,现在的这里是特殊些的Bean,他必须实现FactoryBean接口,实现其方法,程序通过getBean获取实例的时候,他会返回实现的方法中getObject方法的返回值。


三大方法:

1. getObject():负责返回该Bean的实例

2. getObjectType():返回Bean生成的java实例的实现类。

3. isSingleton():是不是单例模式。


该类实现FactoeyBean接口实现其方法,如下:

package com.siti.spring20160305factorybean;

import java.lang.reflect.Field;

import org.springframework.beans.factory.FactoryBean;

public class WangYang implements FactoryBean<Object>{

	private String targetClass;
	private String targetField;

	public String getTargetField() {
		return targetField;
	}

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

	public String getTargetClass() {
		return targetClass;
	}

	public void setTargetClass(String targetClass) {
		this.targetClass = targetClass;
	}

	@Override
	public Object getObject() throws Exception {
		// 反射通过名称查找该类
		Class<?> clazz = Class.forName(this.targetClass);
		// 反射类的属性
		Field field = clazz.getField(targetField);
		// 静态变量
		return field.get(null);
	}

	@Override
	public Class<?> getObjectType() {
		return null;
	}

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

}
配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	 <bean name = "wangyang" class = "com.siti.spring20160305factorybean.WangYang">
	 	<property name="targetClass" value="java.lang.Long"></property>
	 	<property name="targetField" value="MAX_VALUE"></property>
	 </bean>
	 
</beans>

测试代码:

package com.siti.spring20160305factorybean;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainTest {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext20160305.xml");
		System.out.println(context.getBean("wangyang"));
	}
}


获取Bean的id


在某些情况下可能会需要提前知道Bean的id才行,那么下面这个例子会展示怎么利用BeanNameAware接口,拿到配置文件中配置的id。

在配置文件实例化Bean的时候,检测到某个类实现了BeanNameAware这个接口,那么会通过setBeanName方法将Bean的id作为参数beanName注入到这个类的属性中去。

实现BeanNameAware接口,实现它的方法。

package com.siti.spring20160305beanid;

import org.springframework.beans.factory.BeanNameAware;

public class WangYang implements BeanNameAware{

	private String beanName;
	
	@Override
	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}
	
	public void printBeanName(){
		System.out.println(this.beanName);
	}
}
配置文件中将Bean配置进去。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	  <bean name = "wangyang" class = "com.siti.spring20160305beanid.WangYang"></bean>
	  
</beans>
对上面的阐述进行测试:

package com.siti.spring20160305beanid;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.siti.spring20160227.Person;



public class MainTest {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext20160305.xml");
		WangYang wy = context.getBean("wangyang", WangYang.class);
		wy.printBeanName();
	}
}

这里会拿到wy实例的id的。


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值