Spring 框架中注入或替换方法实现
无状态Bean的作用域是singleton单实例,如果我们向singleton的BeanA注入prototype的BeanB,并希望每次调用BeanA的getBeanB()时都能返回一个新的BeanB,这样的要求使用传统的注入方式是无法实现的。因为singleton的Bean注入关联Bean的动作只发生一次,虽然BeanB的作用域是prototype类型,但通过getBeanB()返回的对象还是最开始注入的那个beanB。
所以如果希望每次调用BeanA的getBeanB()时都能返回一个新的BeanB的一种可选的方案是:让BeanA实现BeanFactoryAware接口,从而能够访问容器,然后以下面这种方式来实现。
首先配置XML:
beanauthor的scope设置为prototype。
Book类实现BeanFactoryAware接口:
publicclassBookimplementsBeanFactoryAware{
...
@Override
publicvoidsetBeanFactory(BeanFactorybeanFactory)throwsBeansException{
this.factory=beanFactory;
}
publicAuthorgetPrototypeAuthor(){
return(Author)factory.getBean("author");
}
}
单元测试:
ApplicationContextcontext;
@BeforeMethod
publicvoidsetUp()throwsException{
context=newClassPathXmlApplicationContext("beans5-5.xml");
}
@Test
publicvoidtest(){
Bookbook=(Book)context.getBean("book");
System.out.println(book.getAuthor().hashCode());
System.out.println(book.getAuthor().hashCode());
System.out.println(book.getPrototypeAuthor().hashCode());
System.out.println(book.getPrototypeAuthor().hashCode());
测试结果
从结果中可以发现,只有从BeanFactory中获取得到的Author实例是不同的。
这种实现把应用与Spring框架绑定在了一起,是否有更好的解决方案呢?有,就是注入方法。
1注入方法
Spring容器依赖于CGLib库,所以可以在运行期动态操作Class的字节码,比如动态地创建Bean的子类或实现类。
BookInterface接口:
publicinterfaceBookInterface{
AuthorgetAuthor();
}
XML配置:
单元测试:
BookInterfacebook=(BookInterface)context.getBean("book2");
Assert.assertEquals("毛姆",book.getAuthor().getName());
Assert.assertTrue(book.getAuthor().hashCode()!=book.getAuthor().hashCode());
通过这种配置方式,就可以为接口提供动态实现啦,而且这样返回的Bean都是新的实例。
所以,如果希望在一个singletonBean中获取一个prototypeBean时,就可以使用lookup来实现注入方法。
2替换方法
在Spring中,可以使用某个Bean的方法去替换另一个Bean的方法。
假设Book中有一个getName()方法,用于获取书名:
/**
*书名
*/
privateStringname;
publicStringgetName(){
returnname;
}
我们现在新建一个Bean,它实现了MethodReplacer接口,用于替换Book中的getName()方法:
publicclassBook4implementsMethodReplacer{
@Override
publicObjectreimplement(Objectobj,Methodmethod,Object[]args)throwsThrowable{
return"活着";
}
}
配置:
测试:
Bookbook=(Book)context.getBean("book3");
assertEquals("活着",book.getName());
总结
以上所述是小编给大家介绍的Spring框架中注入或替换方法实现,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!