【Java】Spring之基于注释的容器配置(四)
本文内容纲要:
- 注释是否比配置Spring的XML更好?- Spring开启注释
- Spring常用注释
- @Required
- @Autowired
- @Primary
- @Resource
- @PostConstruct 和 @PreDestroy
- @Component
- @Configuration
- @ComponentScan
- @Bean 和 @Configuration
- @ImportResource
- @Value
- @Profile
注释是否比配置Spring的XML更好?
基于注释的配置的引入引发了这种方法是否比XML“更好”的问题。答案是每种方法都有其优点和缺点,通常,由开发人员决定哪种策略更适合他们。由于它们的定义方式,注释在其声明中提供了大量上下文,从而导致更短更简洁的配置。但是,XML擅长在不触及源代码或重新编译它们的情况下连接组件。一些开发人员更喜欢将布线靠近源,而另一些开发人员则认为注释类不再是POJO,而且配置变得分散且难以控制。
无论选择如何,Spring都可以兼顾两种风格,甚至可以将它们混合在一起。
注意:
1 注释注入在XML注入之前执行。因此,XML配置会覆盖通过这两种方法连接的属性的注释。
Spring开启注释
1、context:annotation-config :是用于激活那些已经在spring容器里注册过的bean(无论是通过xml的方式还是通过package sanning的方式)上面的注解。
2、context:component-scan:除了具有context:annotation-config的功能之外,context:component-scan还可以在指定的package下扫描以及注册javabean 。
Spring常用注释
@Required
@Required注释适用于bean属性setter方法,此批注指示必须在配置时通过bean定义中的显式属性值或通过自动装配填充受影响的bean属性。如果尚未填充受影响的bean属性,则容器将引发异常。
1 public class SimpleMovieLister { 2
3 private MovieFinder movieFinder;
4
5 @Required
6 public void setMovieFinder(MovieFinder movieFinder) {
7 this.movieFinder = movieFinder;
8 }
9
10 // ...
11 }
@Autowired
可以将@Autowired注释应用于构造函数,还可以将@Autowired注释应用于“传统”setter方法,还可以将注释应用于具有任意名称和多个参数的方法
1 public class MovieRecommender { 2
3 private final CustomerPreferenceDao customerPreferenceDao;
4
5 @Autowired
6 private MovieCatalog movieCatalog;
7
8 @Autowired
9 public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
10 this.customerPreferenceDao = customerPreferenceDao;
11 }
12
13 @Autowired(required = false)
14 public void setMovieFinder(MovieCatalog movieCatalog) {
15 this.movieCatalog = movieCatalog;
16 }
17
18 // ...
19 }
@Primary
由于按类型自动装配可能会导致多个候选人,因此通常需要对选择过程进行更多控制。实现这一目标的一种方法是使用Spring的@Primary
注释。@Primary
表示当多个bean可以自动装配到单值依赖项时,应该优先选择特定的bean。如果候选者中只存在一个主bean,则它将成为自动装配的值。
1 @Configuration 2 public class MovieConfiguration {
3
4 @Bean
5 @Primary
6 public MovieCatalog firstMovieCatalog() { ... }
7
8 @Bean
9 public MovieCatalog secondMovieCatalog() { ... }
10
11 // ...
12 }
@Resource
@Resource采用名称属性。默认情况下,Spring将该值解释为要注入的bean名称。换句话说,它遵循按名称语义,如以下示例所示:
如果未明确指定名称,则默认名称是从字段名称或setter方法派生的。如果是字段,则采用字段名称。在setter方法的情况下,它采用bean属性名称
1 public class SimpleMovieLister {2
3 private MovieFinder movieFinder;
4
5 @Resource(name="myMovieFinder")
6 public void setMovieFinder(MovieFinder movieFinder) {
7 this.movieFinder = movieFinder;
8 }
9 }
@PostConstruct 和 @PreDestroy
一个bean进行初始化时,回调@PostConstruct注释的方法
一个bean进行销毁时,回调@PreDestroy注释的方法
1 public class CachingMovieLister { 2
3 @PostConstruct
4 public void populateMovieCache() {
5 // populates the movie cache upon initialization...
6 }
7
8 @PreDestroy
9 public void clearMovieCache() {
10 // clears the movie cache upon destruction...
11 }
12 }
@Component
表示一个带注释的类是一个“组件”,成为Spring管理的Bean。当使用基于注解的配置和类路径扫描时,这些类被视为自动检测的候选对象。同时
@Component是任何Spring管理组件的通用构造型。@Repository,@Service和,@Controller是@Component更具体的用例的专业化(分别在持久性,服务和表示层)。因此,您可以来注解你的组件类有 @Component,但是,通过与注解它们@Repository,@Service或者@Controller ,你的类能更好地被工具处理,或与切面进行关联。
1 package com.test.spring.beanannotation; 2
3 import org.springframework.context.annotation.Scope;
4 import org.springframework.stereotype.Component;
5
6 // @Component("beanAnno")
7 @Component
8 // @Scope("prototype")
9 @Scope
10 public class BeanAnnotation {
11
12 public void say(String arg) {
13 System.out.println("BeanAnnotation:" + arg);
14 }
15
16 public void myHashCode() {
17 System.out.println("BeanAnnotation:" + this.hashCode());
18 }
19
20 }
@Component还是一个元注解。
1 @Target(ElementType.TYPE)2 @Retention(RetentionPolicy.RUNTIME)
3 @Documented
4 @Component
5 public @interface Service {
6
7 // ....
8 }
@Configuration
声明当前类是一个配置类(相当于一个Spring配置的xml文件)
@ComponentScan
自动扫描指定包
1 @Configuration2 @ComponentScan(basePackages = "org.example")
3 public class AppConfig {
4 ...
5 }
简洁起见,前面的示例可能使用value了注释的属性(即@ComponentScan("org.example"))
替代方法使用XML:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 https://www.springframework.org/schema/beans/spring-beans.xsd
7 http://www.springframework.org/schema/context
8 https://www.springframework.org/schema/context/spring-context.xsd">
9
10 <context:component-scan base-package="org.example"/>
11
12 </beans>
@Bean 和 @Configuration
Spring的新Java配置支持中的中心工件是 @Configuration注释类和@Bean注释方法。
该@Bean注释被用于指示一个方法实例,配置和初始化为通过Spring IoC容器进行管理的新对象。对于那些熟悉Spring的
对类进行注释@Configuration表明其主要目的是作为bean定义的来源。此外,@Configuration类允许通过调用@Bean同一类中的其他方法来定义bean间依赖关系。最简单的@Configuration类如下:
1 @Configuration2 public class AppConfig {
3
4 @Bean
5 public MyService myService() {
6 return new MyServiceImpl();
7 }
8 }
上面的AppConfig类等效于以下Spring
<beans> <bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
还可以@Bean
使用接口(或基类)返回类型声明您的方法
@Bean
注释支持指定任意初始化和销毁回调方法
1 public class BeanOne { 2
3 public void init() {
4 // initialization logic
5 }
6 }
7
8 public class BeanTwo {
9
10 public void cleanup() {
11 // destruction logic
12 }
13 }
14
15 @Configuration
16 public class AppConfig {
17
18 @Bean(initMethod = "init")
19 public BeanOne beanOne() {
20 return new BeanOne();
21 }
22
23 @Bean(destroyMethod = "cleanup")
24 public BeanTwo beanTwo() {
25 return new BeanTwo();
26 }
27 }
@ImportResource
虽然Spring提倡零配置,但是还是提供了对xml文件的支持,这个注解就是用来加载xml配置的。例:@ImportResource({"classpath"})
@Value
值得注入。经常与Sping EL表达式语言一起使用,注入普通字符,系统属性,表达式运算结果,其他Bean的属性,文件内容,网址请求内容,配置文件属性值等等
1 package com.test.spring.beanannotation.javabased; 2
3 import org.springframework.beans.factory.annotation.Value;
4 import org.springframework.context.annotation.Bean;
5 import org.springframework.context.annotation.Configuration;
6 import org.springframework.context.annotation.ImportResource;
7
8 @Configuration
9 @ImportResource("classpath:config.xml")
10 public class StoreConfig {
11
12 @Value("${jdbc.url}")
13 private String url;
14 @Value("${jdbc.password}")
15 private String password;
16 @Value("${jdbc.username}")
17 private String username;
18
19 @Bean
20 public MyDriverManager myDriverManager() {
21 return new MyDriverManager(url, username, password);
22 }
23
24 }
@Profile
通过@Profile 注释,您可以指示当一个或多个指定的配置文件处于活动状态时,组件符合注册条件。使用前面的示例,按如下方式重写配置:
1 @Configuration 2 @Profile("development")
3 public class StandaloneDataConfig {
4
5 @Bean
6 public DataSource dataSource() {
7 return new EmbeddedDatabaseBuilder()
8 .setType(EmbeddedDatabaseType.HSQL)
9 .addScript("classpath:com/bank/config/sql/schema.sql")
10 .addScript("classpath:com/bank/config/sql/test-data.sql")
11 .build();
12 }
13 }
如果@Configuration标记了类,则除非一个或多个指定的配置文件处于活动状态,否则将绕过与该类关联的@Profile所有@Bean方法和 @Import注释。如果a @Component或@Configurationclass被标记@Profile({"p1", "p2"}),则除非已激活配置文件'p1'或'p2',否则不会注册或处理该类。如果给定的配置文件以NOT运算符(!)作为前缀,则仅在配置文件未激活时才注册带注释的元素。例如,@Profile({"p1", "!p2"})如果配置文件“p1”处于活动状态或配置文件“p2”未激活,则会发生注册
本文内容总结:注释是否比配置Spring的XML更好?,Spring开启注释,Spring常用注释, @Required, @Autowired, @Primary, @Resource, @PostConstruct 和 @PreDestroy, @Component, @Configuration, @ComponentScan, @Bean 和 @Configuration, @ImportResource, @Value, @Profile,
原文链接:https://www.cnblogs.com/h--d/p/11438566.html
以上是 【Java】Spring之基于注释的容器配置(四) 的全部内容, 来源链接: utcz.com/z/296464.html