8. 基于【注解(Annotation)】的容器配置
8.1. 应该用 XML 还是 Annotation?
8.2. @Required
示例1:
package webj2ee;
import org.springframework.beans.factory.annotation.Required;
public class ExampleBean {
private String name;
@Required
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "ExampleBean{" +
"name='" + name + '\'' +
'}';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
<bean id="exampleBean" class="webj2ee.ExampleBean"/>
</beans>
package webj2ee;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
ExampleBean exampleBean = context.getBean("exampleBean", ExampleBean.class);
System.out.println(exampleBean);
context.close();
}
}
8.3. @Autowired
示例1:(只有一个构造函数,没必要标记 @Autowired)
package webj2ee;
public class MovieFinder {
@Override
public String toString() {
return "MovieFinder{}";
}
}
package webj2ee;
public class SimpleMovieLister {
private MovieFinder movieFinder;
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
@Override
public String toString() {
return "SimpleMovieLister{" +
"movieFinder=" + movieFinder +
'}';
}
// ...
}
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<context:annotation-config/>
<bean id="movieFinder" class="webj2ee.MovieFinder"/>
<bean id="simpleMovieLister" class="webj2ee.SimpleMovieLister"/>
</beans>
package webj2ee;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
SimpleMovieLister simpleMovieLister = context.getBean("simpleMovieLister", SimpleMovieLister.class);
System.out.println(simpleMovieLister);
context.close();
}
}
示例2:(@Autowired + setter)
package webj2ee;
public class MovieFinder {
@Override
public String toString() {
return "MovieFinder{}";
}
}
package webj2ee;
import org.springframework.beans.factory.annotation.Autowired;
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
@Override
public String toString() {
return "SimpleMovieLister{" +
"movieFinder=" + movieFinder +
'}';
}
// ...
}
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<context:annotation-config/>
<bean id="movieFinder" class="webj2ee.MovieFinder"/>
<bean id="simpleMovieLister" class="webj2ee.SimpleMovieLister"/>
</beans>
package webj2ee;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
SimpleMovieLister simpleMovieLister = context.getBean("simpleMovieLister", SimpleMovieLister.class);
System.out.println(simpleMovieLister);
context.close();
}
}
示例3:(@Autowired + required=false)
package webj2ee;
public class MovieFinder {
@Override
public String toString() {
return "MovieFinder{}";
}
}
package webj2ee;
import org.springframework.beans.factory.annotation.Autowired;
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired(required = false)
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// @Autowired
// public void setMovieFinder(@Nullable MovieFinder movieFinder) {
// this.movieFinder = movieFinder;
// }
// @Autowired
// public void setMovieFinder(Optional<MovieFinder> movieFinder) {
// this.movieFinder = movieFinder.orElse(null);
// }
@Override
public String toString() {
return "SimpleMovieLister{" +
"movieFinder=" + movieFinder +
'}';
}
// ...
}
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<context:annotation-config/>
<bean id="simpleMovieLister" class="webj2ee.SimpleMovieLister"/>
</beans>
package webj2ee;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
SimpleMovieLister simpleMovieLister = context.getBean("simpleMovieLister", SimpleMovieLister.class);
System.out.println(simpleMovieLister);
context.close();
}
}
示例4:(@Autowired + Set、Array、Map)
package webj2ee;
public interface MovieCatalog {
}
package webj2ee;
import org.springframework.core.annotation.Order;
@Order(1)
public class Comedy implements MovieCatalog {
@Override
public String toString() {
return "Comedy{}";
}
}
package webj2ee;
import org.springframework.core.annotation.Order;
@Order(2)
public class Dracula implements MovieCatalog {
@Override
public String toString() {
return "Dracula{}";
}
}
package webj2ee;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
public class MovieRecommender {
@Autowired
private MovieCatalog[] movieCatalogsArr;
@Autowired
private Set<MovieCatalog> movieCatalogsSet;
@Autowired
private Map<String, MovieCatalog> movieCatalogsMap;
@Override
public String toString() {
return "MovieRecommender{" +
"movieCatalogsArr=" + Arrays.toString(movieCatalogsArr) +
", movieCatalogsSet=" + movieCatalogsSet +
", movieCatalogsMap=" + movieCatalogsMap +
'}';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<context:annotation-config/>
<bean id="dracula" class="webj2ee.Dracula"/>
<bean id="comedy" class="webj2ee.Comedy"/>
<bean id="movieRecommender" class="webj2ee.MovieRecommender"/>
</beans>
package webj2ee;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
MovieRecommender movieRecommender = context.getBean("movieRecommender", MovieRecommender.class);
System.out.println(movieRecommender);
context.close();
}
}
示例5:(@Autowired + Constructors + Multi-Elements)
package webj2ee;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
public class MovieRecommender {
private MovieCatalog[] movieCatalogsArr;
private Set<MovieCatalog> movieCatalogsSet;
private Map<String, MovieCatalog> movieCatalogsMap;
@Autowired(required = true)
public MovieRecommender(
MovieCatalog[] movieCatalogsArr,
Set<MovieCatalog> movieCatalogsSet,
Map<String, MovieCatalog> movieCatalogsMap) {
this.movieCatalogsArr = movieCatalogsArr;
this.movieCatalogsSet = movieCatalogsSet;
this.movieCatalogsMap = movieCatalogsMap;
}
@Override
public String toString() {
return "MovieRecommender{" +
"\nmovieCatalogsArr=" + Arrays.toString(movieCatalogsArr) +
", \nmovieCatalogsSet=" + movieCatalogsSet +
", \nmovieCatalogsMap=" + movieCatalogsMap +
'}';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<context:annotation-config/>
<bean id="movieRecommender" class="webj2ee.MovieRecommender"/>
</beans>
示例6:(@Autowired + ApplicationContext ...)
package webj2ee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
public class SimpleMovieLister {
@Autowired
private ApplicationContext context;
@Override
public String toString() {
return "SimpleMovieLister{" +
"context=" + context +
'}';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<context:annotation-config/>
<bean id="simpleMovieLister" class="webj2ee.SimpleMovieLister"/>
</beans>
package webj2ee;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
SimpleMovieLister simpleMovieLister = context.getBean("simpleMovieLister", SimpleMovieLister.class);
System.out.println(simpleMovieLister);
context.close();
}
}
8.4. @Autowired + @Primary
package webj2ee;
import org.springframework.beans.factory.annotation.Autowired;
public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
@Override
public String toString() {
return "MovieRecommender{" +
"movieCatalog=" + movieCatalog +
'}';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<context:annotation-config/>
<bean id="dracula" class="webj2ee.Dracula" primary="true"/>
<bean id="comedy" class="webj2ee.Comedy"/>
<bean id="movieRecommender" class="webj2ee.MovieRecommender"/>
</beans>
package webj2ee;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
MovieRecommender movieRecommender = context.getBean("movieRecommender", MovieRecommender.class);
System.out.println(movieRecommender);
context.close();
}
}
8.5. @Autowired + @Qualifier
标准用法:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<context:annotation-config/>
<bean id="dracula" class="webj2ee.Dracula">
<qualifier value="level1"></qualifier>
</bean>
<bean id="comedy" class="webj2ee.Comedy">
<qualifier value="level2"></qualifier>
</bean>
<bean id="movieRecommender" class="webj2ee.MovieRecommender"/>
</beans>
package webj2ee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class MovieRecommender {
@Autowired
@Qualifier("level1")
private MovieCatalog movieCatalog;
@Override
public String toString() {
return "MovieRecommender{" +
"movieCatalog=" + movieCatalog +
'}';
}
}
8.6. @Resource
示例:
package webj2ee;
import org.springframework.context.ApplicationContext;
import javax.annotation.Resource;
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource
private ApplicationContext context;
@Resource(name = "movieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
@Override
public String toString() {
return "SimpleMovieLister{" +
"movieFinder=" + movieFinder +
", context=" + context +
'}';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<context:annotation-config/>
<bean id="movieFinder" class="webj2ee.MovieFinder"/>
<bean id="simpleMovieLister" class="webj2ee.SimpleMovieLister"/>
</beans>
9. Classpath Scanning and Managed Components
<beans>
<context:component-scan base-package="org.example">
<context:include-filter type="regex"
expression=".*Stub.*Repository"/>
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
</beans>
下一波就轮到写
AOP实践篇咯
参考:
Spring Framework Runtime: https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/overview.html The IoC Container: https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#spring-core Inversion of Control Containers and the Dependency Injection pattern: https://martinfowler.com/articles/injection.html 《Java Web 高级编程技术》 《Spring 入门经典》 《精通 Spring 4.x 企业应用开发实战》 《Spring5 高级编程》 《Spring实战(第3版)》