1. @Configuration注解
@Configuration注解的意义就是告诉 Spring框架,当前这个类就是配置文件,代替以前的 xml 配置文件。通常需要联合@ComponentScan注解一起使用。
2.@ComponentScan注解
扫描指定包 ,把里面带注解(注解指的是包下所有加了 @Service、@Component、@Repository 的类)的类自动创建对象、放进 Spring 容器。
将创建的对象放入Spring容器中后,就可以使用相关方法从Spring容器中获取Bean对象了:
java
// 1. 加载配置类,启动Spring容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(你的配置类.class);
// 2. 根据【类型】拿Bean(最常用、推荐)
UserService service = ctx.getBean(UserService.class);
// 3. 根据【Bean名字】拿Bean
Object bean = ctx.getBean("方法名");
3.@Bean注解
在配置类里,把方法返回对象交给 Spring 容器管理,替代 <bean> 标签。这里为什么要将方法返回的对象交给Spring容器管理,因为有些第三方类无法手动添加@Component等注解(比如:
DataSource、Druid连接池、事务管理器、第三方工具类),只能使用相关方法创建第三方类的对象。我们将这些复杂的创建对象方式打包整合成为一个方法,为这个方法标记@Bean注解。
学会了上面几种全注解形式,我们就可以将之前的代码逻辑转换为全注解形式的代码了。
首先创建一个Config包,在包中创建一个名为Config的java类,写入前两个注解表示当前类是Spring的配置类:
java
package com.newFile.Config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.newFile")
public class Config {
//这里可以放置@Bean配置
}
Spring的配置类
@Bean注解不仅仅可以在Spring的配置类中使用,在其他普通类中也可以使用。Spring的配置类功能可以参考之前Spring配置文件功能,
对比项 普通类 加了 @Configuration的配置类作用 写业务逻辑 定义 Spring 容器的配置规则 扫描方式 被 @ComponentScan扫到才会注册启动时直接被 AnnotationConfigApplicationContext加载@Bean 效果 普通类里的 @Bean 是「lite 模式」,不做 Bean 依赖的 CGLIB 代理 配置类里的 @Bean 是「full 模式」,会用 CGLIB 生成代理,保证单例和依赖正确性 而且很多Spring的高级功能如AOP等都需要在配置类上开启注解:@EnableTransactionManagement:开启注解事务(让 @Transactional 生效)
@EnableAspectJAutoProxy:开启 AOP 自动代理
@EnableWebMvc:开启 Spring MVC 配置
配置类中不能创建Spring容器!!!也就是说配置类中不能出现:ApplicationContext ctx = new AnnotationConfigApplicationContext("你的配置类路径");
需要注意的是,这里当我们使用@Component或其他注解标注一个类Bean容器同时使用了@Bean注解标注了创建这个类的方法时,再从Spring容器中通过getBean方法获取这个类的bean对象时会报错,因为不能同时有两个相同类Bean对象的创建方法。
但是@Bean注解是可以和@Value注解一起使用的。
Config类中:
java
package com.newFile.Config;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.newFile.dao.User;
@Configuration
@ComponentScan("com.newFile")
public class Config {
//这里可以放置@Bean配置
// 创建一个简单的方法来获取User对象
@Bean(value = "getUser")
public User getUser(){
return new User();
}
}
User类中:
java
package com.newFile.dao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//这里将Component注解注释掉防止多个类Bea对象的冲突
//@Component(value = "user1")
public class User {
@Value("1")
int id;
@Value("mei")
String name;
@Value("19")
int age;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//记得创建一个无参构造方法
public User() {
}
public User(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
最后编写测试类:
java
import com.newFile.Config.Config;
import com.newFile.dao.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test{
@org.junit.Test
public void test() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
User user = (User)ctx.getBean("getUser");
System.out.println(user);
}
}
最后的运行结果:
