Spring 注解整理

更多内容,前往 IT-BLOG

一、核心容器


【1】@Configuration:告诉 Spring 这是一个配置类(配置类=配置文件)
【2】@Bean:给容器中注册一个 Bean ;类型为返回值类型,id 默认是用方法名作为 id 也可以通过 value 属性添加 id(相当于 xml 中的 <bean> 标签),主要用于导入第三方包里面的组件。
【3】@ComponentScan:包扫描,只要标注了 @Cotroller、@Service、@Repository、@Componet 等注解便会自动注入此类,excludeFilters 属性可以定义需要排除的注解或者类,通过 @Filter 数组进行定义,type 属性为类型(注解、类、正则、自定义的 TypeFilter 等等)class 为排除的类或注解类。includeFilters 属性指定只需要扫描包含的注解或者类,但需要关闭默认的扫描包注解的规则:useDefaultFilters=false默认为 true。主要用于导入自己定义的组件。

 1 @Configuration
 2 @ComponentScan(value="com.atyintong"/*,excludeFilters= {
 3         @Filter(type=FilterType.ANNOTATION,classes={Controller.class,Service.class})
 4 },useDefaultFilters=false,includeFilters= {
 5         @Filter(type=FilterType.ANNOTATION,classes=Service.class)
 6 }*/)
 7 public class MainConfig {
 8     @Bean
 9     public Person persion() {
10         return new Person("zzx",12);
11     }
12 }

【4】获取配置文件的方式:new AnnotationConfigApplicationContext(MainConfig.class)

1 AnnotationConfigApplicationContext application=new AnnotationConfigApplicationContext(MainConfig.class);
2 @Test
3 public void test() {
4     Person person = application.getBean(Person.class);
5     System.out.println(person);
6 }
7 /*输入内容如下:Person [name=zzx, age=12, nickName=null]*/

【5】@scope默认为 singleton 表示单实例,容器启动时调用方法创建对象放到 ioc 容器中,以后每次调用时直接从中获取。常用的还有 prototype 表示多实例,容器启动时不创建对象,每当调用时才创建当前对象。

1 @Scope(value="prototype")
2 @Bean
3 public Person persion() {

【6】@lazy:懒加载,单实例 bean 默认在容器启动时不创建对象,第一次获取对象的时候创建对象。以后调用不再创建对象。
【7】@Conditonal({Condition}):按照一定条件进行判断,放在配置类的方法上表示,满足条件才给容器注册 bean。也可以放在类上表示,满足条件才执行配置类。首先需要自定义一个实现 Condition 接口的类,如下:

 1 public class TestCondition implements Condition{
 2 
 3     @Override
 4     public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
 5         // 1、context:判断条件能使用的上下文环境
 6         // 2、metadata:注释信息
 7         // 1.1 获取当前环境信息
 8         Environment environment = context.getEnvironment();
 9         // 1.2 获取bean的注册类信息
10         BeanDefinitionRegistry registry = context.getRegistry();
11         String property = environment.getProperty("os.name");
12         if(property.contains("Windows") && !registry.containsBeanDefinition("person")) {
13             return true;
14         }
15         return false;
16     }
17 
18 }

 在配置内中加载两个不同的 Persion对象,并在 person01 对象加载方法前加入 @Conditional 注解,查看是否加载此对象。

 1 @Bean
 2 public Person person() {
 3     return new Person("zzx",12);
 4 }
 5 
 6 @Conditional(TestCondition.class)
 7 @Bean("person01")
 8 public Person person01() {
 9     return new Person("lisi",13);
10 }
11 /* IOC 容器启动时,不包含person01 对象,因为Conditional 条件返回为 false */

【8】@Import:导入组件,id 默认是组件的全类名。

 1 @Import({Cat.class,MyImportSelector.class})  //输出的结果为:com.atyintong.bean.Cat
 2 @Configuration
 3 public class MainConfig {
也可以将需要导入的组件集合定义在一个继承了 ImportSelector 的类中,并将此类通过 @Import 注解导入到容器中,如下:
1 public class MyImportSelector implements ImportSelector{
2 
3      @Override
4      public String[] selectImports(AnnotationMetadata importingClassMetadata) {
5                  // 通过全类名,导入需要的组件
6          return new String[] {"com.atyintong.bean.Color"};
7      }
8 }

【9】@FactoryBean:使用 Spring 提供的 FactoryBean (工厂Bean)。默认获取到的是工厂 bean 调用 getObject() 创建的对象,而要获取工厂 Bean 本身需要给 id 前面加一个 & 标识。如下:

 1 /**
 2  * @ClassName:       CarFactoryBean
 3  * @Description:    实现 FactoryBean 接口,并在泛型中传入需要实例化的类
 4  * @author:          zzx
 5  * @date:            2019年1月13日        下午11:12:45
 6  */
 7 public class CarFactoryBean implements FactoryBean<Car> {
 8 
 9     @Override
10     public Car getObject() throws Exception {
11         // 创建泛型中的对象,对象会添加到容器中
12         return new Car();
13     }
14 
15     @Override
16     public Class<?> getObjectType() {
17         // 对象的类型
18         return Car.class;
19     }
20 
21     @Override
22     public boolean isSingleton() {
23         // true 表示对象是单例,false 表示多实例
24         return true;
25     }
26 
27 }

 对上述理论的测试:

 1 @Test
 2 public void testFactory() {
 3     Object car0 = application.getBean("carFactoryBean");
 4     Object car1 = application.getBean("carFactoryBean");
 5     Object car2 = application.getBean("&carFactoryBean");
 6     //输入为 true,因为是单实例
 7     System.out.println(car0 == car1);
 8     //输出:com.atyintong.bean.Car@3d299e3
 9     System.out.println(car1);
10     //输出:com.atyintong.condition.CarFactoryBean@55a561cf
11     System.out.println(car2);
12 }

二、Bean 的声明周期


【1】bean 指定初始化和销毁方法:通过指定 initMethod 属性指定初始化方法,destroyMethod 属性指定销毁方法。其中 init 和 destroy 方法是 Car 对象中定义的方法。

1 @Bean(initMethod="init",destroyMethod="destory")
2 public Car car() {
3     return new Car();
4 }

【2】类通过实现 InitializingBean DisposableBean接口

 1 public class Cat implements InitializingBean,DisposableBean{
 2 
 3     @Override
 4     public void destroy() throws Exception {
 5         // 定义销毁逻辑
 6     }
 7 
 8     @Override
 9     public void afterPropertiesSet() throws Exception {
10         // 定义初始化逻辑
11     }
12 }

【3】@PostConstruct:对象创建并赋值之后调用,@PreDestory:容器移除对象之前。

 1 public class Color {
 2     //对象创建并赋值之后调用
 3     @PostConstruct
 4     public void init() {
 5         
 6     }
 7     //容器移除对象之前
 8     @PreDestroy
 9     public void destory() {
10         
11     }
12 }

【4】后置处理器:BeanPostProcessor 在类的 init 方法前执行 postProcessBeforeInitialization 方法中任务,在初始化 init 之后执行 postProcessAfterInitialization 方法。

 1 @Component
 2 public class MyBeanPostProcess implements BeanPostProcessor{
 3 
 4     @Override
 5     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
 6         //bean 表示当前类的全类名,beanName 表示容器中的 id
 7         /*  测试输入:构造函数。。。
 8             com.atyintong.bean.Car@1b083826---->car
 9             init 初始化方法,创建对象之前
10             com.atyintong.bean.Car@1b083826---->car */
11         System.out.println(bean+"---->"+beanName);
12         return bean;
13     }
14 
15     @Override
16     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
17         System.out.println(bean+"---->"+beanName);
18         return bean;
19     }
20 
21 }

三、组件赋值


【1】@Value():进行属性赋值操作

1 public class Person {
2     //使用@Value赋值;
3         //1、基本数值
4         //2、可以写SpEL; #{}
5         //3、可以写${};取出配置文件【properties】中的值(在运行环境变量里面的值)
6         
7         @Value("${person.name}")
8         private String name;

【2】@PropertySource()引入配置文件时使用,通过 ${key} 获取配置内容

@PropertySource(value= {"classpath:/Persion.properties"})
public class MainConfig {

【3】@Autowired():自动注入,默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class) ,如果找到多个相同类型的组件,再将属性的名称作为组件 id 去容器中查找。但可以使用 @Qualifier("xxx") 指定需要装配的组件的 id ,而不使用属性名。自动装备一定要将属性赋值号,如果没有在容器中找到此属性,就会报 notfoundxxx错误,或者指定自动加载的 required 属性为 false ,就不必须加载此类也不用报错。

@Service
public class BookService {
    @Qualifier("bookDao1")
    @Autowired(required=false)
    private BookDao bookDao;

 当容器中存在多个同类对象时,我可以某个上添加@primary注解,当自动注入时,就会优先注入。

@Primary
@Bean("person01")
public Person person01() {

【4】@Resource:与@Autowired 一样实现自动装配功能,默认是按照组件名称进行装配。不支持 @primary 注解和 required属性。

@Resource(name="bookDao")
private BookDao bookDao;

【5】@Inject:需要导入 javax.inject 包,和 @Autowired 功能一样,但其没有 required 属性。@Autowired:Spring 定义的,@Resource、@Inject 都是 java 规范。

@Inject
private BookDao bookDao;


 ----关注公众号,获取更多内容----

posted @ 2020-11-21 23:46  Java程序员进阶  阅读(39)  评论(0编辑  收藏  举报