一、在未被spring管理的对象中对 容器中的对象引用
获取BeanFactory
要对sping 窗口中的对象进行操作,首先第一步是需要拿到beanFactory 的引用
spring 提供了一个接口,我们可以利用此接口做一此事情达到我们的期望。
org.springframework.beans.factory.BeanFactoryAware 接口
public void setBeanFactory(BeanFactory beanFactory) throws BeansException;
实现此方法,我们就可以拿到一个beanfactory的引用 了,只需要把beanfacotry用static变量引用起来就可以使用了
代码实现例子
/***
* spring factory 操作类
* 需要配置到spring中
* @author 胡真山
* 2015年9月8日
*/
@Service("mySpringBeanLocator")
public class SpringBeanLocator implements BeanFactoryAware,BeanNameAware {
/**保存beanname 这样我们就不需要与配置文件中的配置 id 进行耦合*/
private static String BEAN_NAME;
/**保存spring中的beanfactory*/
private static BeanFactory beanFactory = null;
/**单例*/
private static SpringBeanLocator instance;
public void setBeanFactory(BeanFactory beanFactory) throws BeansException{
SpringBeanLocator.beanFactory=beanFactory;
}
/**
* 获取spring的beanfactory
* @return
*/
public BeanFactory getBeanFactory() {
return beanFactory;
}
public String getBeanName(){
return BEAN_NAME;
}
public static SpringBeanLocator getInstance() {
if (instance == null){
instance = (SpringBeanLocator) beanFactory.getBean(BEAN_NAME);
}
return instance;
}
/***
* 获取spring中的bean对象
* @param name
* @return
*/
public Object getBean(String name){
return beanFactory.getBean(name);
}
@Override
public void setBeanName(String name) {
BEAN_NAME=name;
}
}
然后我们就可以通过 SpringBeanLocator.getInstance().getBean(String name) 方式来获取spring容器中的对象了。
二、在末被spring管理的对象中使用注解引用spring中的对象
还是在SpringBeanLocator类中进行扩展
实现方法
1、自动以名称赋值
/***
* 把注解式的bean加载到未被spring管理的类上
* @param serviceBean 目录对象
* @throws Exception
*/
public void loadResourceProperites(Object serviceBean) throws Exception{
Set<Field> fieldset=getClassFields(serviceBean.getClass());
for(Field f:fieldset){
Object value=f.get(serviceBean);
if(value==null){
Resource resoure=f.getAnnotation(Resource.class);
String name=resoure.name();
if(StringUtils.isEmpty(name)){
name=f.getName();
}
value=getBean(name);
f.set(serviceBean, value);
}
}
}
2、以类名赋值
/**
* 自动注入spring中的bean为属性
* @param bean
*/
public void autowireBeanPropertiesByName(Object bean){
((AutowireCapableBeanFactory)beanFactory).autowireBeanProperties(bean,AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
}
通过些方法我们把配置了Resource 注解的字段 从值从spring中加载对象以达到注解注入属性的效果
使用例子
例如struts 的action 都是没有使用spring管理的 ,这样就不能直接通过配置注入spring 中的service ;
使用时需要把SpringBeanLocator配置到spring配置文件中
<bean id="beanLocator" class="org.smile.spring.SpringBeanLocator">
</bean>
这种情况就可以通过以后说的两种方法中的一种方式来实现
第一种:
在action 父类中添加方法:
public Object getBean(String id){
return SpringBeanLocator.getInstance().getBean(id);
}
第二种:
1、重写validate方法 配置注解属性加载注入action对象
public void validate(){
try {
SpringBeanLocator.getInstance().loadResourceProperites(this);
} catch (Exception e) {
e.printStackTrace();
}
super.validate() ;
}
2、使用autowireBeanPropertiesByName方法
@Resource
private PurPaymentService purPaymentService;
public RunJobTask(){
try{
//注解注入属性
SpringBeanLocator.getInstance().autowireBeanPropertiesByName(this);
}catch(Throwable er){
er.printStackTrace();
}
}
然后在子类中配置注解 就可以直接引用spring中的bean了
public class PaymentAction extends AbstractBaseAction{
@Resource
private PurPaymentService purPaymentService;
}
通过这两个方法 都可以实现从Spring容器中给purPaymentService 属性被赋值了