最近项目开始用spring。最恼火的地方是在spring外部实例化的bean需要获得ioc的功能。
发现有俩种模式。
1.BeanFactoryAware接口方式。需要myclass extends BaseAutoAware。
用于第三方组件通过反射newInstance业务类时,获取注入。
public class BaseLocator implements BeanFactoryAware{
private static BeanFactory factory;
public void setBeanFactory(BeanFactory f) throws BeansException {
factory = f;
}
public BeanFactory getFactory(){
return factory;
}
}
public class BaseAutoAware {
public BaseAutoAware() {
((AutowireCapableBeanFactory)retrieveBeanFactory())
.autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
}
private BeanFactory retrieveBeanFactory() {
BaseLocator bl=new BaseLocator();
return bl.getFactory();
}
}
class A extends BaseautoAware{
@autowired
private service s;
say(){
s.execute();
}
}
class Test{
//spring外部实例化
A a=new A();
a.say();
}
2.FactoryBean方式。
用于工厂getBean。示例代码如下。每增加一个类,就要修改工厂。除非有很特殊个性的初始化,否则不建议使用这种方式
@Configuration
//非spring工厂
public class MyFactoryBean {
private static Logger logger = Logger.getLogger(MyFactoryBean.class);
public MyService getBean(String name) {
if (name != null && name.equals("myname")) {
return create1();
} else
return create2();
}
@Bean
public MyService create2() {
return new MyService2();
}
@Bean
public MyService create1() {
return new MyService1();
}
}
@Controller
public class Hello {
@Autowired
private MyFactoryBean mf;
public String getName(String name){
MyService ms=mf.getBean(name);
ms.execute();
return "hello world "+name;
}
}
3.对于第二种,比较合理的方法是利用ApplicationContextAware 接口,做个浅封装的代理工厂,然后就可以Object object = ctx.getBean(beanName);优点是增加类时,不需要改动代码。
@Service
public class SpringHolder implements ApplicationContextAware {
private static Logger logger = Logger.getLogger(SpringHolder.class);
private static ApplicationContext ctx=null;
public MyService getBean(String s) {
logger.debug("get bean"+s);
return ctx.getBean(s,MyService.class);
}
@Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
ctx=arg0;
}
}