方式一(推荐):
思路:
获取AutowireCapableBeanFactory对象,然后调用注入bean对象方法.
代码:
主要调用ApplicationContextUtils.newAutoWiredInstance()方法生成已经注入springbean的实例.
工具类:
@Component
public class ApplicationContextUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
//方式一:传Class对象
//新建对象实例并注入其他springbean
public static <T> T newAutoWiredInstance(Class<T> beanClass){
return (T)applicationContext.getAutowireCapableBeanFactory()
.autowire(beanClass, AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);
}
//方式二:传bean对象
//已经new出来的对象进行注入
public static <T> T autowire(T bean){
applicationContext.getAutowireCapableBeanFactory()
.autowireBeanProperties(bean, AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);
return bean;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextUtils.applicationContext = applicationContext;
}
}
自己的类(不受spring管理的bean):
public class AutoWiredBean {
@Autowired
private ServiceA serviceA;
@Autowired
private ServiceB serviceB;
public void test(){
serviceB.sayHello();
}
}
测试:
//自己new对象
AutoWiredBean autoWiredBean1 = new AutoWiredBean();
ApplicationContextUtils.autowire(autoWiredBean1);
autoWiredBean1.test();
//只是传Class对象
AutoWiredBean autoWiredBean = ApplicationContextUtils.newAutoWiredInstance(AutoWiredBean.class);
autoWiredBean.test();
方式二(不推荐):
思路:
1. 自己搞个类,注入ApplicationContext,然后构造方法里面对类的属性进行反射注入.
2. 然后需要自己new的类都来集成这个类
理解:initNewService因为是被spring容器管理的,且实现了ApplicationContextAware(或者ServletContextAware),所以在spring容器初始化的时候回注入ApplicationContextAware,我们把它保存在类中,并设置为static,因此每个继承此类的对象都能拿到ApplicationContextAware。然后继承类初始化的时候,我们通过属性的类型到容器中找到对应的对象,并通过反射注入进来。
代码:
@Service
public class InitNewService implements ApplicationContextAware {
private static Logger logger = LoggerFactory.getLogger(InitNewService.class);
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* 将继承此类的service中的字段(注解了@Autowired 或者@Resource)等注入进来
*/
public InitNewService(){
if (this.applicationContext == null){
return;
}
if (this.getClass().isAnnotationPresent(org.springframework.stereotype.Service.class)
|| this.getClass().isAnnotationPresent(org.springframework.stereotype.Controller.class)
|| this.getClass().isAnnotationPresent(org.springframework.stereotype.Component.class) ){
return;
}
Class clazz = this.getClass();
do {
Field[] fields = clazz.getDeclaredFields();
for (Field f : fields) {
if (f.isAnnotationPresent(org.springframework.beans.factory.annotation.Autowired.class)
|| f.isAnnotationPresent(javax.annotation.Resource.class)){
try {
String simpleName = f.getType().getSimpleName();
String beanName = StrUtils.toLowerCaseFirstOne(simpleName);
Object bean = applicationContext.getBean(beanName);
if (bean == null){
return;
}
boolean accessible = f.isAccessible();
f.setAccessible(true);
f.set(this,bean);
f.setAccessible(accessible);
}catch (Exception e){
logger.error(clazz.getName() + "当new对象注入类" + f.getName() + "的时候,发生了错误",e);
e.printStackTrace();
}
}
}
clazz = clazz.getSuperclass();
} while (clazz != Object.class);
}
}