您现在的位置是:亿华云 > 系统运维
Spring框架之基于Java的容器注解
亿华云2025-10-04 03:48:09【系统运维】4人已围观
简介我们将介绍如何在Java代码中使用注解来配置Spring容器。它包括:Basic Concepts: @Bean and @Configuration。Instantiating the 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类如下:
@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,如下例子:
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 时特别有用。下面的例子展示了如何做到这一点。
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类做如下注释。
@Configuration
@ComponentScan(basePackages = "com.acme")
public class AppConfig {
// ...
}Bean的依赖
@Configuration
public class AppConfig {
@Bean
public TransferService transferService(AccountRepository accountRepository) {
return new TransferServiceImpl(accountRepository);
}
}生命周期回调
任何用@Bean注解定义的类都支持常规的生命周期回调,并且可以使用JSR-250的@PostConstruct和@PreDestroy注解。如果一个bean实现了InitializingBean、DisposableBean或Lifecycle,它们各自的方法将被容器调用。
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作用域章节。
@Configuration
public class MyConfiguration {
@Bean
@Scope("prototype")
public Encryptor encryptor() {
// ...
}
}自定义bean名称
默认情况下,配置类使用@Bean方法的名称作为Bean的名称。可以通过name属性来自定义名称,如下:
@Configuration
public class AppConfig {
@Bean("myThing")
public Thing thing() {
return new Thing();
}
}Bean别名
@Configuration
public class AppConfig {
@Bean({ "dataSource", "subsystemA-dataSource", "subsystemB-dataSource"})
public DataSource dataSource() {
// instantiate, configure and return DataSource bean...
}
}Bean注入之间的依赖
@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注入来访问。亿华云
@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:
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到应用上下文中。
@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);
}
}
</beans>@PropertySource
我们将讨论如何使用@PropertySource来读取属性文件,并用@Value和Environment来显示值。
@PropertySource注解为向Spring的环境添加PropertySource提供了一种方便的声明性机制。要与@Configuration类一起使用。
假设我们从config.properties文件中读取数据库配置,并使用Environment将这些属性值设置为DataSourceConfig类。
@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文件
@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接口,源码下载它可以分层次地解析消息。
account.name=TestAccount@Configuration
public class AppConfig {
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("config/messages");
return messageSource;
}
}@Service
public class AccountService {
@Autowired
private MessageSource messageSource;
public void someMsg() {
messageSource.getMessage("account.name", null, Locale.ENGLISH);
//todo
}
}很赞哦!(6213)
相关文章
- 4、企业无形资产:通用网站已成为企业网络知识产权的重要组成部分,属于企业的无形资产,也有助于提升企业的品牌形象和技术领先形象。它是企业品牌资产不可或缺的一部分。
- 再见,正则表达式
- 快醒醒,C# 9 中又来了一堆关键词 Init,Record,With
- 为什么排序的复杂度为O(N log N)
- 第五步:重复第四步,直到找到正确的纪录。
- 在 CentOS/RHEL 7/6 上安装最新 PHP 7 软件包的 3 种方法
- 详解 Python 的二元算术运算,为什么说减法只是语法糖?
- 一张脑图带你掌握Git命令
- 3、不明先知,根据相关征兆预测可能发生的事件,以便提前做好准备,赶紧注册相关域名。;不差钱域名;buchaqian抢先注册,就是这种敏感类型。预言是最敏感的状态。其次,你应该有眼力。所谓眼力,就是善于从社会上时不时出现的各种热点事件中获取与事件相关的域名资源。眼力的前提是对域名领域的熟悉和丰富的知识。
- 一文知晓HTTP的长连接和短连接