【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 @Configuration

2 @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的XML配置的人来说,@Bean注释与元素扮演的角色相同。你可以@Bean在任何Spring中使用-annotated方法 @Component。但是,它们最常用于@Configuration豆类。

  对类进行注释@Configuration表明其主要目的是作为bean定义的来源。此外,@Configuration类允许通过调用@Bean同一类中的其他方法来定义bean间依赖关系。最简单的@Configuration类如下:

1 @Configuration

2 public class AppConfig {

3

4 @Bean

5 public MyService myService() {

6 return new MyServiceImpl();

7 }

8 }

  上面的AppConfig类等效于以下Spring XML:

<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

回到顶部