publicclassExampleBean {// Number of years to calculate the Ultimate Answerprivateint years;// The Answer to Life, the Universe, and EverythingprivateString ultimateAnswer;publicExampleBean(int years,String ultimateAnswer) {this.years= years;this.ultimateAnswer= ultimateAnswer; }}
publicclassExampleBeanWithConstructorProperties {// Number of years to calculate the Ultimate Answerprivateint years;// The Answer to Life, the Universe, and EverythingprivateString ultimateAnswer; @ConstructorProperties({"years","ultimateAnswer"})publicExampleBeanWithConstructorProperties(int years,String ultimateAnswer) {this.years= years;this.ultimateAnswer= ultimateAnswer; }}
基于Setter的注入
Setter注入主要用来无参构造器或者获得对象实例之后才设置对象的属性。下面是Setter的例子:
publicclassSimpleMovieLister {// the SimpleMovieLister has a dependency on the MovieFinderprivateMovieFinder movieFinder;// a setter method so that the Spring container can inject a MovieFinderpublicvoidsetMovieFinder(MovieFinder movieFinder) {this.movieFinder= movieFinder; }// business logic that actually uses the injected MovieFinder is omitted...}
对于的XML文件如下:
<!--Setter DI --> <beanid="movieFinder"class="com.flydean.beans.MovieFinder"/> <beanid="simpleMovieLister"class="com.flydean.beans.SimpleMovieLister"> <propertyname="movieFinder"ref="movieFinder"/> </bean>
<beanid="simpleMovieLister"class="com.flydean.beans.SimpleMovieLister"autowire="byType"> </bean><!--Setter DI --> <beanid="movieFinder"class="com.flydean.beans.MovieFinder"> <propertyname="name"value="movie"/> <propertyname="number"value="123456"/> </bean>
SimpleMovieLister如下:
packagecom.flydean.beans;importlombok.Data;@DatapublicclassSimpleMovieLister {// the SimpleMovieLister has a dependency on the MovieFinderprivateMovieFinder movieFinder;// a setter method so that the Spring container can inject a MovieFinderpublicvoidsetMovieFinder(MovieFinder movieFinder) {this.movieFinder= movieFinder; }// business logic that actually uses the injected MovieFinder is omitted...}
publicclassCommandManagerimplementsApplicationContextAware {privateApplicationContext applicationContext;publicObjectprocess(Map commandState) {// grab a new instance of the appropriate CommandCommand command =createCommand();// set the state on the (hopefully brand new) Command instancecommand.setState(commandState);returncommand.execute(); }protectedCommandcreateCommand() {// notice the Spring API dependency!returnthis.applicationContext.getBean("command",Command.class); }publicvoidsetApplicationContext(ApplicationContext applicationContext) throwsBeansException {this.applicationContext= applicationContext; }}
这种方法并不可取的,因为业务代码和Spring框架产生了耦合。方法注入是Spring IoC 容器的一个高级特性,它可以很好的处理这种情况。
publicabstractclassCommandManagerB {publicObjectprocess(Map commandState) {// grab a new instance of the appropriate Command interfaceAsyncCommand command =createCommand();returnnull; }// okay... but where is the implementation of this method?publicabstractAsyncCommandcreateCommand();}
这里我们定义了一个抽象类,要查找的方法就是createCommand。返回的对象类,如下:
publicclassAsyncCommand {}
下面是XML配置文件:
<!-- a stateful bean deployed as a prototype (non-singleton) --> <beanid="myCommand"class="com.flydean.beans.AsyncCommand"scope="prototype"><!-- inject dependencies here as required --> </bean><!-- commandProcessor uses statefulCommandHelper --> <beanid="commandManager"class="com.flydean.beans.CommandManagerB"> <lookup-methodname="createCommand"bean="myCommand"/> </bean>
publicclassReplacementComputeValueimplementsMethodReplacer {publicObjectreimplement(Object o,Method m,Object[] args) throwsThrowable {// get the input value, work with it, and return a computed resultString input = (String) args[0];return"def"; }}