您的位置:首页 > Web前端 > JavaScript

web项目运行时(如JSON parse)手动注入@Autowired等注解的属性值-1

2017-07-27 16:04 465 查看
1.需求:通过JSON parse成具体对象,对象中有@Autowired,@Resource注解的属性如何注入?

Spring Bean管理的Spring注解的@Autowired或者@Resource属性在项目启动时会交由Spring自动注入具体的属性值,如果我不将Bean交由Spring管理,正常情况下@Autowired,@Resource注解也不会起作用,如何在运行时手动注入被加上@Autowired或者@Resource的属性呢?

2.方案探讨

(1)创建一个被Spring管理的bean,bean中有很多@Autowire的属性,在JSON.parseObject后通过BeanUtils.copyProperties()将属性值copy过来

(2)在构造方法中加入通过applicationContext.getBean(“beanName”)获取到Spring Bean给当前注解属性赋值

(3)拿到当前类的所有属性,再拿到用@Autowired或者@Resource注解的属性,再拿到属性的类型通过applicationContext.getBean(beanType)获得到Spring Bean给当前注解属性赋值

3.方案实行

(1)方案1比较简单,略过

(2)方案2:

SpringContextUtil :

/**
* Created by Kowalski on 2017/7/27
* Updated by Kowalski on 2017/7/27
*/
public class SpringContextUtil implements ApplicationContextAware{
private static ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}

public static ApplicationContext getApplicationContext() {
return applicationContext;
}

public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}

public static Object getBean(Class requiredType) throws BeansException {
return applicationContext.getBean(requiredType);
}
}


TestBean :

public class TestBean {

@Autowired
private TestInterface testInterface;

TestBean() {
this.testInterface= (TestInterface) SpringContextUtil.getBean("testInterface");
}
}


(3)方案3:

最终 我们采用了方案3,因为维护起来比较方便

Utils:简易版

/**
* Created by Kowalski on 2017/7/27
* Updated by Kowalski on 2017/7/27
*/
@Slf4j
public class Utils {
public static void initServce(Object object){
/**获得所有属性(包括私有不包括父类)*/
Field[] fields = object.getClass().getDeclaredFields();

for(Field field:fields){
if(field.getAnnotation(Autowired.class) != null || field.getAnnotation(Resources.class) != null){
/**可设置私有属性*/
field.setAccessible(true);
/**拿到单例Service 放入对象属性中*/
try {
field.set(object, SpringContextsUtil.getApplicationContext().getBean(field.getType()));
}catch (IllegalAccessException e){
log.error("Utils initServce IllegalAccessException:{}", e);
}catch (Exception e){
log.error("Utils initServce set filed:{} failed:{}", field.getType(), e);
}
}
}
}
}


Utils:增加本地缓存版

/**
* Created by Kowalski on 2017/7/27
* Updated by Kowalski on 2017/7/27
* 活动引擎工具类
*/
@Slf4j
public class Utils {

/**静态缓存*/
private static final ConcurrentMap<Class<?>, ConcurrentMap<Field, Object>> map = new ConcurrentHashMap<Class<?>, ConcurrentMap<Field, Object>>();
/**
* 初始化bean时(如json parse)注入Service属性
* 放在构造方法中初始化(Utils.initServce(this);)
* @param object
*/
public static void initServce(Object object) {

Map<Field, Object> filedsBeansFromMap = map.get(object.getClass());

if (filedsBeansFromMap != null) {
/**遍历Filed与Spring Bean对应关系*/
for (Map.Entry<Field, Object> filedsBeans : filedsBeansFromMap.entrySet()) {
try {
filedsBeans.getKey().set(object, filedsBeans.getValue());
} catch (IllegalAccessException e) {
log.error("Utils initServce IllegalAccessException:{}", e);
}
}
return;
}
/**获得所有属性(包括私有不包括父类)*/
Field[] fields = object.getClass().getDeclaredFields();
/**Filed与Spring Bean对应关系*/
ConcurrentMap<Field, Object> tofiledsBeansMap = new ConcurrentHashMap<Field, Object>();
for (Field field : fields) {
/**只针对Autowired 与 Resources注解属性使用*/
if (field.getAnnotation(Autowired.class) != null || field.getAnnotation(Resources.class) != null) {
try {
/**设置私有属性可写*/
field.setAccessible(true);
/**拿到单例Service 放入对象属性中*/
Object bean = SpringContextsUtil.getApplicationContext().getBean(field.getType());
/**给属性赋值*/
field.set(object, bean);
tofiledsBeansMap.putIfAbsent(field, bean);
} catch (IllegalAccessException e) {
log.error("Utils initServce IllegalAccessException:{}", e);
} catch (Exception e) {
log.error("Utils initServce set filed failed:{}", e);
}
}
}
map.putIfAbsent(object.getClass(), tofiledsBeansMap);
}
}


TestBean :

public class TestBean {

@Autowired
private TestInterface testInterface;

TestBean() {
Utils.initServce(this);
}
}


有更好方案的小伙伴欢迎探讨~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐