1. @Configuration && @Bean
1.1. 一、@Configuration
@Configuration注解标注在类上,相当于把该类作为Spring的xml配置文件中的<beans/>,作用是:配置spring容器(应用上下文)
1. Configuration注解配置类
/**
* 使用java注解代替常用的xml来进行spring配置
*
* @see Configuration
* @see Bean
*/
@Configuration
public class AnnotationMain {
public static final Logger LOGGER = LoggerFactory.getLogger(AnnotationMain.class);
public AnnotationMain(){
LOGGER.info("Spring容器启动初始化");
}
}
相当于:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd" default-lazy-init="false">
</beans>
2. main方法进行测试:
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationMain.class);
}
}
查看输出日志,发现Spring容器已启动了。
Connected to the target VM, address: '127.0.0.1:51621', transport: 'socket'
2017-09-26 16:33:13.476 [main] INFO org.springframework.context.annotation.AnnotationConfigApplicationContext [581] - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1e67a849: startup date [Tue Sep 26 16:33:13 CST 2017]; root of context hierarchy
2017-09-26 16:33:13.651 [main] INFO samples.spring.AnnotationMain [20] - Spring容器启动初始化
Disconnected from the target VM, address: '127.0.0.1:51621', transport: 'socket'
1.2. 二、@Bean
@Bean标注在方法上(返回某个实例的方法),等价于spring的xml配置文件中的<bean>,作用为:注册bean对象
1. Bean对象
public class User {
private static final Logger LOGGER = LoggerFactory.getLogger(User.class);
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void init(){
LOGGER.info("user init method called.");
}
public void destroy(){
LOGGER.info("user destroy method called.");
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
public class UserAdapter {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
2. @Bean注解配置
@Configuration
public class AnnotationMain {
public static final Logger LOGGER = LoggerFactory.getLogger(AnnotationMain.class);
public AnnotationMain(){
LOGGER.info("Spring容器启动初始化");
}
@Bean
public User user() {
User user = new User();
user.setName("test");
user.setId(1);
return user;
}
@Bean(name = "user2", initMethod = "init", destroyMethod = "destroy")
@Scope("prototype")
public User user2(){
User user2 = new User();
user2.setName("user2");
user2.setId(2);
return user2;
}
@Bean
public UserAdapter userAdapter(User user){
UserAdapter userAdapter = new UserAdapter();
userAdapter.setUser(user);
return userAdapter;
}
}
3. main方法
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationMain.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
LOGGER.info("beanName:{}", beanDefinitionName);
}
User user = applicationContext.getBean("user", User.class);
User user1 = applicationContext.getBean("user", User.class);
LOGGER.info("user:{} user.equals(user1)={}", user, user.equals(user1));
User user2 = applicationContext.getBean("user2", User.class);
User user22 = applicationContext.getBean("user2", User.class);
LOGGER.info("user2:{}, user2.equals(user22)={}", user2, user2.equals(user22));
UserAdapter userAdapter = applicationContext.getBean(UserAdapter.class);
LOGGER.info("userAdapter.user: {}", userAdapter.getUser());
}
}
输出的测试结果:
2017-09-26 17:33:16.293 [main] INFO org.springframework.context.annotation.AnnotationConfigApplicationContext [581] - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1e67a849: startup date [Tue Sep 26 17:33:16 CST 2017]; root of context hierarchy
2017-09-26 17:33:16.479 [main] INFO samples.spring.AnnotationMain [24] - Spring容器启动初始化
2017-09-26 17:33:16.528 [main] INFO samples.spring.beans.User [30] - user init method called.
Disconnected from the target VM, address: '127.0.0.1:52117', transport: 'socket'
2017-09-26 17:33:16.572 [main] INFO samples.spring.App [21] - beanName:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
2017-09-26 17:33:16.574 [main] INFO samples.spring.App [21] - beanName:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
2017-09-26 17:33:16.574 [main] INFO samples.spring.App [21] - beanName:org.springframework.context.annotation.internalRequiredAnnotationProcessor
2017-09-26 17:33:16.574 [main] INFO samples.spring.App [21] - beanName:org.springframework.context.annotation.internalCommonAnnotationProcessor
2017-09-26 17:33:16.574 [main] INFO samples.spring.App [21] - beanName:org.springframework.context.event.internalEventListenerProcessor
2017-09-26 17:33:16.575 [main] INFO samples.spring.App [21] - beanName:org.springframework.context.event.internalEventListenerFactory
2017-09-26 17:33:16.575 [main] INFO samples.spring.App [21] - beanName:annotationMain
2017-09-26 17:33:16.575 [main] INFO samples.spring.App [21] - beanName:org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
2017-09-26 17:33:16.575 [main] INFO samples.spring.App [21] - beanName:org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor
2017-09-26 17:33:16.575 [main] INFO samples.spring.App [21] - beanName:user2
2017-09-26 17:33:16.575 [main] INFO samples.spring.App [21] - beanName:user
2017-09-26 17:33:16.575 [main] INFO samples.spring.App [21] - beanName:userAdapter
2017-09-26 17:33:16.575 [main] INFO samples.spring.App [26] - user:User{id=1, name='test'} user.equals(user1)=true
2017-09-26 17:33:16.575 [main] INFO samples.spring.beans.User [30] - user init method called.
2017-09-26 17:33:16.576 [main] INFO samples.spring.beans.User [30] - user init method called.
2017-09-26 17:33:16.576 [main] INFO samples.spring.App [30] - user2:User{id=2, name='user2'}, user2.equals(user22)=false
2017-09-26 17:33:16.576 [main] INFO samples.spring.App [33] - userAdapter.user: User{id=1, name='test'}
4. 总结
@Bean注解用在标注@Configuration类的返回实例的方法上;@Bean常用的参数有:name: 指定bean的名称,如果未指定,则默认使用方法名相同;initMethod: 初始化方法destroyMethod: 销毁方法
- @Bean注解默认作用域为单例singleton作用域,可通过@Scope(“prototype”)设置为原型作用域;
- 标注了
@Bean的方法的参数可以根据参数名称注入方法,如public UserAdapter userAdapter(User user)会把名称为user的bean注入此方法。