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框架中注入或替换方法实现,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!