有的class在创建的时候,需要一些外来的参数当做构造函数的参数。
在类上加@Component或者其他注解时,该类会交给spring来管理,自动创建对象。自己new出来的 Bean 是不会被spring托管的,包括new的Bean里面又需要注入其他对象或者需要注入配置文件中的属性的时候,会出现空指针。
要解决问题,有两种不一样的思路。
- 不使用 new,而都是用spring来创建 Bean。
- 找到 Bean 并加载。
1 是比较容易理解,应该也是较为推荐的方式。需要解决的问题其实是怎么规避自己new的问题。Spring的方式是使用
@Configuration 和 @Bean 注解来解决传参的问题。
package SpringStudy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import SpringStudy.Model.Counter;
import SpringStudy.Model.Piano;
@Configuration
public class SpringConfig {
@Bean
public Piano piano(){
return new Piano();
}
@Bean(name = "counter")
public Counter counter(){
return new Counter(12,"Shake it Off",piano());
}
}
譬如就可以上面的Bean里面,就可以注入 Counter 这个 Bean 的对象了。
这样就解决了没有无参构造函数的问题。
另一个方式就更为初级,就是如果有使用java的build模式创建的对象,需要怎么注入。对于有些框架,可以将参数写入properties文件里面,然后就可以直接注入了。
(如果死活不对可以尝试mvn清空缓存,重启idea之类的……)
2 就是参考enjoy_Day@csdn的解决方案,自己实现 ApplicationContextAware 的方法。自己根据类的类型手动获得加载后的bean即可。
@Component
public class GetBeanUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (GetBeanUtil.applicationContext == null) {
GetBeanUtil.applicationContext = applicationContext;
}
}
/**
* 返回ApplicationContext
*
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 返回bean
*
* @param beanName beanName
* @return bean
*/
public static Object getBean(String beanName) {
return applicationContext.getBean(beanName);
}
/**
* 获取bean
*
* @param c c
* @param <T> 泛型
* @return bean
*/
public static <T> T getBean(Class<T> c) {
return applicationContext.getBean(c);
}
/**
* 获取bean
* @param c c
* @param name 名称
* @param <T> 泛型
* @return T 泛型
*/
public static <T> T getBean(String name, Class<T> c) {
return getApplicationContext().getBean(name, c);
}
}
使用的时候
public class AreaInvadeAnalyzer extends Analyzer {
private AreaInvadeMapper areaInvadeMapper =GetBeanUtil.getBean(AreaInvadeMapper.class);
....其他代码省略
}
网友评论