zoukankan      html  css  js  c++  java
  • spring注解

    一、组件注册

    1、@Configuration和@Bean

    • @Configuration:告诉spring这是一个配置类。配置类==配置文件,可使用注解在这个类中进行配置文件中的配置。
    • @Bean:给容器中注册一个Bean,类型为返回值类型,id默认使用方法名为id。可修改
    • 使用AnnotationConfigApplicationContext来从容器中读取bean。

    2、@ComponentScan

    与.xml配置文件中的扫描包相同。

    1)、属性:

    value:要扫描的包

    excludeFilters=Filter[]:指定扫描的时候按照什么规则排除哪些组件

    includeFilters=Filter[]:指定扫描的时候只需要那些组件。需要将默认过滤关闭useDefaultFilters = false才有用,否则全部都会被导入。

    //将com.atguigu包及其子包下的有@Controller和@Service的组件添加到容器中,
    @Configuration@ComponentScan(value = "com.atguigu" ,         includeFilters = {@Filter(type = FilterType.ANNOTATION,classes = {Controller.class,Service.class})},         useDefaultFilters = false)public class MainConfig {
    

    @ComponentScan是可重复注释,可以扫描多个包,或者用@ComponentScans来配置多个@ComponentScan

    2)、TypeFilter指定过滤规则

    • ANNOTATION 按照注释

    • ASSIGNABLE_TYPE 按照给定的类型

    • REGEX 正则表达式

    • CUSTOM 自定义规则。

    自定义过滤规则

    实现TypeFilter接口

    public class MyTypeFilter implements TypeFilter {
        /**
        * metadataReader:读取当前正在扫描的类
        * metadataReaderFactory:可以获取到任何类的信息
        */
        @Override
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
            throws IOException {
            //获取当前正在扫描类的注解信息
            AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
            //获取当前正在扫描类的类信息
            ClassMetadata classMetadata = metadataReader.getClassMetadata();         //获取当前类资源
            Resource resource = metadataReader.getResource();
            if(classMetadata.getClassName().contains("er")) {//将类名带有er的扫描进容器
                return true;
            }
            return false;
        }
    }
    

    3、@Scope设置组件作用域

    相当于bean标签中的scope属性

    • prototype:多实例。每次获取时才会调用方法,并且每一次获取都会调用一次
    • singleton:单实例的。(默认值):ioc容器启动时就会调用方法创建对象放到ioc容器中,以后每次获取就是直接从容器中拿
    • request:同一次请求创建一个实例
    • session:同一个session创建一个实例

    4、@Lazy (bean懒加载)

    只针对单例而言。

    单例bean,默认在容器启动时创建对象

    使用懒加载,在第一次获取时创建实例

    5、@Conditional(按条件判断注册)

    public @interface Conditional {
        /**
        * All {@link Condition Conditions} that must {@linkplain Condition#matches match}
        * in order for the component to be registered.
        */
        Class<? extends Condition>[] value();
    }
    

    参数类型为Class数组,可通过实现Condition接口的类来进行条件判断

    满足当前条件,配置的bean才能生效。放在类上,可以对类中的组件统一设置

    例:在linux环境下才注册一个bean

    //作为条件要实现Condition接口
    public class LinuxCondition implements Condition {
        /**
        * ConditionContext:判断条件能使用的上下文环境
        * AnnotatedTypeMetadata:注释信息
        */
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            Environment environment = context.getEnvironment();
            String property = environment.getProperty("os.name");
            if(property.equals("Linux")) {
                return true;
            }
            return false;
        }
    }
    
    

    使用

    @Conditional({LinuxCondition.class})
    @Bean("linux")
    public Person person3() {
        return new Person("linus",50);
    }
    

    6、@Import

    1)、快速给容器中导入一个组件。

    id默认为全类名。

    @Import(要导入容器的组件)。容器就会自动注册这个组件,默认id为全类名。

    2)、实现自定义逻辑返回需要的组件

    1. importSelector:返回要导入组件的全类名数组。

    创建一个实现了接口ImportSelector的类,实现方法selectImports方法,可以在内部书写自定义的逻辑,返回的数组要是全类名,并且不能为空指针,最低为空数组。

    public class MyImportSelect implements ImportSelector{
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Red"};
        }
    }
    
    @Import({Color.class,MyImportSelect.class})
    

    在导入这个实现类时就会将自定义的组件({"com.atguigu.bean.Blue","com.atguigu.bean.Red"})导入容器中,而不是将实现类导入容器中。

    2. ImportBeanDefinitionRegistrar接口

    与ImportSelector功能相同,可以将要添加的组件注册到容器中

    7、FactoryBean注册组件

    工厂Bean获取的是调用getObject创建的对象

    创建一个实现了FactoryBean接口的类

    public class ColorFactoryBean implements FactoryBean<Color> {
        @Override
        public Color getObject() throws Exception {
            return new Color();
        }
        @Override
        public Class<?> getObjectType() {
            return Color.class;
        }
        @Override
        public boolean isSingleton() {
            // TODO Auto-generated method stub
            return FactoryBean.super.isSingleton();
        }
    }
    
    • getObejct:返回一个对象,这个对象会添加到容器中

    • getObjectType:返回对象的类型

    • isSingleton:是否是单例

    配置Bean

    @Bean
    public ColorFactoryBean colorFactoryBean() {
        return new ColorFactoryBean();
    }
    

    测试FactoryBean,结果为Color。若通过id获取bean时在id前加上&符,那么变回获取工厂本身,或者通过类型获取

    @Test
    public void testFactoryBean() {
        Object bean = ioc.getBean("colorFactoryBean");
        System.out.println(bean.getClass());
    }//获取到Color
    
    @Test
    public void testFactoryBean() {
        Object bean = ioc.getBean("&colorFactoryBean");
        System.out.println(bean.getClass());
    }//获取到ColorFactoryBean
    

    二、生命周期(指定初始化和销毁方法)

    1、@Bean指定初始化和销毁方法

    默认由容器来管理bean的声明周期。但我们可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。

    1. 指定初始化和销毁方法。像bean标签里的init-method和destroy-method方法。
    2. 在Bean注解中对应有initMethod方法和destroyMethod方法
    3. 初始化:对象创建完成并且属性赋值完毕。销毁:容器关闭。
    4. 多实例:容器不会管理这个bean。不会调用其销毁方法

    2、InitializingBean和DisposableBean接口

    通过让bean实现InitializingBean和DisposableBean接口同样可以指定初始化和销毁方法

    3、@PostConstruct和@PreDestroy

    通过@PostConstruct和@PreDestroy可以实现同样效果。将两个注释分别标注在bean方法的初始化、销毁方法。

    • @PostConstruct:在创建bean并为属性赋值后调用该注解标注的方法

    • @PreDestroy:在容器关闭之前调用该注解标注的方法

    4、BeanPostProcessor

    bean的后置处理器

    在bean初始化前后进行一些处理工作:

    • postProcessorBeforeInitialization:在初始化之前工作

    • postProcessAfterInitializeation:在初始化之后工作

    三、属性赋值

    1、@Value

    1. 基本数值
    2. 可以写SpEL,#{}取出
    3. 可以写${},取出配置文件中的值

    2、@PropertySource

    加载外部配置文件,与xml中的加载外部属性文件功能相同

    四、自动装配

    自动装配:spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值。

    1、Autowired(Spring定义的)

    自动注入。

    • 默认优先按照类型从容器中找对应的组件
    • 如果找到多个相同类型的组件,在将属性的名称作为id到容器中查找
    • @Qualifier(),使用@Qualifier指定要装配的组件id,而不是使用属性
    • 默认一定要将属性赋值好,没有就会报错。可以使用属性required,来指定是否必须要被装配
    • @Primary,让spring进行自动装配的时候,在未指定装配的情况下,默认使用此注解标注的bean作为装配的首选项。若使用了@Qualifier,那么便使用@Qualifier指定的bean的名字

    2、@Resource和@Inject(java规范)

    • @Resource:可以和@Autowired一样实现自动装配功能,默认使用属性的名称装配。不能支持@Primary和requred功能
    • @Inject:需要导入javax.inject的包,和@Autowired的功能一样。但是没有required=false的功能。

    3、方法、构造器位置的自动装配

    1.标注在方法上

    spring容器创建当前对象,就会调用方法,完成赋值

    方法使用的参数,自定义类型的值从ioc容器获取。

    默认加载ioc容器中的组件,容器启动会自动调用无参构造器创建对象,再进行初始化等操作

    2.标注在构造方法上

    如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取

    3.标注在参数上

    4.@Bean标注的方法创建对象的时候,方法参数的值从容器中获取。默认不写@Autowired

    5.都是从ioc容器中获取参数的值

    4.、自定义组件注入底层组件

    自定义组件想要使用spring容器底层的一些组件(ApplicationContext、BeanFactory)

    自定义组件实现xxxAware:在创建对象的时候,会调用接口规定的方法注入相关组件。

    5、@Profile环境搭建

    Profile:Spring为我们提供的可以根据当前环境,动态的激活和切换一些列组件的功能

    1. 加了环境标识的bean,只有这个环境被激活的时候才能够注册到容器中,默认是default环境
    2. 写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
    3. 没有标注环境的bean,在所有的环境下都被加载

    开发环境,测试环境,生产环境

    @Porfile根据环境注册bean

    1.使用命令行动态参数:在虚拟机参数位置加载-Dspring.profiles.actice=test切换到测试环境

    2.使用代码的方式激活某些环境

    @Test
    public void test01() {
    
        //1.创建一个无参的ApplicationContext
        AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext();
    
        //2.设置需要激活的环境
        ioc.getEnvironment().setActiveProfiles("test","prod");
    
        //3.注册主配置类
        ioc.register(MainConfigOfProfile.class);
    
        //4.启动刷新容器
        ioc.refresh();
    
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
    
        for (String name : beanDefinitionNames) {
    
            System.out.println(name);
    
        }
    }
    
  • 相关阅读:
    UIView的常见属性
    Object-C-Foundation-反射
    Object-C-自定义类型归档
    Java集合:HashMap源码剖析
    spring-boot-2.0.3之quartz集成,数据源问题,源码探究
    杂谈篇之我是怎么读源码的,授之以渔
    ElasticSearch 从零到入门
    java实现图片上传功能,并返回图片保存路径
    quartz定时任务及时间设置
    笛子初学者吹什么曲子
  • 原文地址:https://www.cnblogs.com/ylcc-zyq/p/12562679.html
Copyright © 2011-2022 走看看