SpringJava配置
在 Spring 中,也可以不用 XML 文件,转而使用 Java 代码的方式配置。官方文档的例子
@Configuration public class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); } }
The preceding
AppConfig
class is equivalent to the following Spring<beans/>
XML:<beans> <bean id="myService" class="com.acme.services.MyServiceImpl"/> </beans>
这两种方式效果是相同的。现在新建 Spring-07-JavaConfig 项目来试一试。
1. 测试环境搭建
在 com.qiyuan.entity 包下创建一个实体类 User,这里就不用 Lombok 了;同时给 name 属性注入值 Qiyuanc
public class User {
private String name;
public String getName() {
return name;
}
@Value("Qiyuanc")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" + "name=‘" + name + ‘\‘‘ + ‘}‘;
}
}
不使用 XML 文件,怎么才能把这个对象注册成一个 bean 呢(就算是使用注解,也需要在 XML 中开启注解和扫描包)?
2. 使用JavaConfig
2.1 设置配置类
先在 com.qiyuan.config 包中创建一个 MyConfig 类,刚创建完这只是一个普通类,通过 @Configuration 注解把这个类设置为 Spring 的配置类,作用相当于 XML 文件!
@Configuration
// 这个类虽然是配置类,但也会被 Spring 接管,因为 @Configuration 包含了 @Component
public class MyConfig {
}
设置完后就能看到这个类的旁边有小叶子了!
2.2 注册Bean
然后在里面添加一个方法,直接返回一个 User 对象,并在方法上加上 @Bean 的注解;
@Configuration
public class MyConfig {
@Bean
public User getUser(){
return new User();
}
}
这时这个方法旁边也出现了小叶子(点不进去不知道为什么),说明 bean 被 Spring 管理了!
@Configuration 标注在类上,相当于把该类作为 XML 配置文件中的
@Bean 可理解为 XML 中的
标签
2.3 测试获取对象
这时候其实 bean 就已经配置好了,在测试方法中获取对象试一下。
不过获取的方式和 XML 不同,这里要先获取 AnnotationConfigApplicationContext 对象(注解配置应用容器),参数为配置类!
public class MyTest {
@Test
public void Test(){
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User getUser = context.getBean("getUser", User.class);
System.out.println(getUser);
}
}
// 执行结果
// User{name=‘Qiyuanc‘}
没有用 XML 配置也成功获取到对象了!
可以发现,在测试类中 getBean 的参数为 getUser,这就要说到加了 @Bean 注解的方法了
@Bean
public User getUser(){
// 返回值 = calss
// 方法名 = id
return new User();
}
加上 @Bean 注解后,这个方法就相当于一个
2.4 小结
扩展:进入 @Configuration 的源码查看,也能看到 @Component,说明配置类也是一个组件,也会被 Spring 管理!
...
@Component
public @interface Configuration {
...
}
注意:如果使用了 JavaConfig 的方式获取对象,则对应的类上不需要添加 @Component 注解,否则容器中会存在两个对象!
添加 @Component 把类设置为组件,上面的 MyConfig 类不变
@Component
public class User {
...
}
用测试方法获取两个对象,比较它们是否相同
public class MyTest {
@Test
public void Test2(){
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = context.getBean("user", User.class);
User getUser = context.getBean("getUser", User.class);
System.out.println(user);
System.out.println(getUser);
System.out.println(user==getUser);
}
}
// 执行结果
// User{name=‘Qiyuanc‘}
// User{name=‘Qiyuanc‘}
// false
可以看到获取的其实是两个对象!name 相同是因为在 User 类中进行的属性注入。
使用 JavaConfig 配置类时,IoC 容器并没有管理 User 类,管理的其实是 MyConfig 配置类,通过配置类获取到 getUser 对象!如果给 User 类加上 @Component 注解,则 IoC 容器也会管理它,默认产生的对象就是 user,所以会出现两个对象!
3. 总结
使用 JavaConfig,Spring 就可以完全脱离 XML 文件配置(注解还是需要 XML 的),在 SpringBoot 中,这种配置方式用的将更多。
使用 JavaConfig 进行配置的三个步骤
- 配置类 @Configuration
- 需要管理的类
- 添加对应类的 return 方法 @Bean,返回值是 class,方法名是 id
不过最后发现了一个很逆天的问题:去掉 @Configuration 注解,一样能运行,但 @Bean 去掉就找不到对象了。看来 @Bean 才是最关键的??!