好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

详解Java如何使用注解来配置Spring容器

介绍

我们将介绍如何在Java代码中使用注解来配置Spring容器。它包括:

Basic Concepts: @Bean and @Configuration。 Instantiating the Spring Container by Using 。 AnnotationConfigApplicationContext。 Using the @Bean Annotation。 Using the @Configuration annotation。 Composing Java-based Configurations。 Bean Definition Profiles。 PropertySource Abstraction。 Using @PropertySource。 Placeholder Resolution in Statements。

@Bean and @Configuration

@Bean注解用在一个方法上表示实例化、配置和初始化一个新对象,由Spring IoC容器管理。对于那些熟悉Spring的 XML配置的人来说,@Bean注解的作用与元素的作用相同。

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

?

1

2

3

4

5

6

7

8

9

10

11

@Configuration

public class AppConfig {

     @Bean

     public MyService myService() {

         return new MyServiceImpl();

     }

     @Bean

     public OtherService otherService() {

         return new OtherService();

     }

}

AnnotationConfigApplicationContext实例化容器

与实例化

ClassPathXmlApplicationContext时使用Spring XML文件作为输入的方式相同,你可以在实例化AnnotationConfigApplicationContext时使用@Configuration类作为输入。这使得Spring容器的使用完全不需要XML,如下例子:

?

1

2

3

4

5

public static void main(String[] args) {

     ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig. class );

     MyService myService = ctx.getBean(MyService. class );

     myService.doStuff();

}

通过使用 register(Class...) 以编程方式构建容器

你可以通过使用无参数构造函数来实例化AnnotationConfigApplicationContext,然后使用 register() 方法来配置它。这种方法在以编程方式构建 AnnotationConfigApplicationContext 时特别有用。下面的例子展示了如何做到这一点。

?

1

2

3

4

5

6

7

8

public static void main(String[] args) {

     AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();

     ctx.register(AppConfig. class , OtherConfig. class );

     ctx.register(AdditionalConfig. class );

     ctx.refresh();

     MyService myService = ctx.getBean(MyService. class );

     myService.doStuff();

}

@ComponentScan启用组件扫描

为了启用组件扫描,可以在@Configuration类做如下注释。

?

1

2

3

4

5

@Configuration

@ComponentScan (basePackages = "com.acme" )

public class AppConfig  {

     // ...

}

Bean的依赖

?

1

2

3

4

5

6

7

@Configuration

public class AppConfig {

     @Bean

     public TransferService transferService(AccountRepository accountRepository) {

         return new TransferServiceImpl(accountRepository);

     }

}

生命周期回调

任何用@Bean注解定义的类都支持常规的生命周期回调,并且可以使用JSR-250的@PostConstruct和@PreDestroy注解。如果一个bean实现了InitializingBean、DisposableBean或Lifecycle,它们各自的方法将被容器调用。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

public class BeanOne {

 

     public void init() {

         // initialization logic

     }

}

public class BeanTwo {

 

     public void cleanup() {

         // destruction logic

     }

}

@Configuration

public class AppConfig {

 

     @Bean (initMethod = "init" )

     public BeanOne beanOne() {

         return new BeanOne();

     }

     @Bean (destroyMethod = "cleanup" )

     public BeanTwo beanTwo() {

         return new BeanTwo();

     }

}

Bean指定作用域

Bean默认的作用域是singleton,更多Bean作用域可参考Bean作用域章节。

?

1

2

3

4

5

6

7

8

@Configuration

public class MyConfiguration {

     @Bean

     @Scope ( "prototype" )

     public Encryptor encryptor() {

         // ...

     }

}

自定义bean名称

默认情况下,配置类使用@Bean方法的名称作为Bean的名称。可以通过name属性来自定义名称,如下:

?

1

2

3

4

5

6

7

@Configuration

public class AppConfig {

     @Bean ( "myThing" )

     public Thing thing() {

         return new Thing();

     }

}

Bean别名

?

1

2

3

4

5

6

7

@Configuration

public class AppConfig {

     @Bean ({ "dataSource" , "subsystemA-dataSource" , "subsystemB-dataSource" })

     public DataSource dataSource() {

         // instantiate, configure and return DataSource bean...

     }

}

Bean注入之间的依赖

?

1

2

3

4

5

6

7

8

9

10

11

@Configuration

public class AppConfig {

     @Bean

     public BeanOne beanOne() {

         return new BeanOne(beanTwo());

     }

     @Bean

     public BeanTwo beanTwo() {

         return new BeanTwo();

     }

}

@Import

@Import注解表示要导入一个或多个@Configuration类。在导入的@Configuration类中声明的@Bean定义应该通过使用@Autowired注入来访问。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@Configuration

public class ConfigA {

     @Bean

     public A a() {

         return new A();

     }

}

@Configuration

@Import (ConfigA. class )

public class ConfigB {

     @Bean

     public B b() {

         return new B();

     }

}

现在,在实例化上下文时不需要同时指定ConfigA类和ConfigB类,而只需要明确提供ConfigB:

?

1

2

3

4

5

6

public static void main(String[] args) {

     ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB. class );

     // now both beans A and B will be available...

     A a = ctx.getBean(A. class );

     B b = ctx.getBean(B. class );

}

@ImportResource

Spring提供了一个@ImportResource注解,用于从applicationContext.xml文件中加载bean到应用上下文中。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@Configuration

@ImportResource ( "classpath:/com/acme/properties-config.xml" )

public class AppConfig {

     @Value ( "${jdbc.url}" )

     private String url;

     @Value ( "${jdbc.username}" )

     private String username;

     @Value ( "${jdbc.password}" )

     private String password;

     @Bean

     public DataSource dataSource() {

         return new DriverManagerDataSource(url, username, password);

     }

}

?

1

2

3

4

<!-- properties-config.xml -->

< beans >

     < context:property-placeholder location = "classpath:/com/acme/jdbc.properties" />

</ beans >

@PropertySource

我们将讨论如何使用@PropertySource来读取属性文件,并用@Value和Environment来显示值。

@PropertySource注解为向Spring的环境添加PropertySource提供了一种方便的声明性机制。要与@Configuration类一起使用。

假设我们从config.properties文件中读取数据库配置,并使用Environment将这些属性值设置为DataSourceConfig类。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

@Configuration

@PropertySource ( "classpath:config.properties" )

public class ProperySourceDemo implements InitializingBean {

     @Autowired

     Environment env;

     @Override

     public void afterPropertiesSet() throws Exception {

         setDatabaseConfig();

     }

     private void setDatabaseConfig() {

         DataSourceConfig config = new DataSourceConfig();

         config.setDriver(env.getProperty( "jdbc.driver" ));

         config.setUrl(env.getProperty( "jdbc.url" ));

         config.setUsername(env.getProperty( "jdbc.username" ));

         config.setPassword(env.getProperty( "jdbc.password" ));

         System.out.println(config.toString());

     }

}

支持多个properties文件

?

1

2

3

4

5

6

7

8

@Configuration

  @PropertySources ({

   @PropertySource ( "classpath:config.properties" ),

   @PropertySource ( "classpath:db.properties" )

  })

  public class AppConfig {

   //...

  }

ApplicationContext

ApplicationContext实现了BeanFactory接口,并提供了如下功能:

通过MessageSource接口,访问i18n风格的消息。 通过ResourceLoader接口访问资源,如URL和文件。 事件发布,即通过使用ApplicationEventPublisher接口,向实现ApplicationListener接口的bean发布。 通过HierarchicalBeanFactory接口加载多个(分层的)上下文,让每个上下文专注于一个特定的层,例如一个应用程序的Web层。

MessageSource 国际化

ApplicationContext接口扩展了一个名为MessageSource的接口,因此,它提供了国际化("i18n")功能。Spring还提供了HierarchicalMessageSource接口,它可以分层次地解析消息。

?

1

account.name=TestAccount

?

1

2

3

4

5

6

7

8

9

@Configuration

public class AppConfig {

     @Bean

     public MessageSource messageSource() {

       ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();

       messageSource.setBasename( "config/messages" );

       return messageSource;

     }

}

?

1

2

3

4

5

6

7

8

9

10

@Service

public class AccountService {

     @Autowired

     private MessageSource messageSource;

    

     public void someMsg() {

         messageSource.getMessage( "account.name" , null , Locale.ENGLISH);

         //todo

     }

}

以上就是详解Java如何使用注解来配置Spring容器的详细内容,更多关于Java注解配置Spring容器的资料请关注其它相关文章!

原文链接:https://developer.51cto.com/article/711132.html

查看更多关于详解Java如何使用注解来配置Spring容器的详细内容...

  阅读:17次