Spring 第二 随笔记

【spring除了XML配置外,还有注解类配置,这个就主要讲注解类配置】

package com.abc.config;

import com.abc.condition.LinuxCondition;
import com.abc.condition.WindowsCondition;
import com.abc.domain.Color;
import com.abc.domain.Person;
import com.abc.domain.Student;
import com.abc.myTypeFilter;
import org.springframework.context.annotation.*;
import org.springframework.context.annotation.ComponentScan.Filter;
/**
 * excludeFilters 排除过滤容器的对象
 * includeFilters 包含容器对象
 */
/**
 * 一个 ComponentScans 【这个带 s 哦】 里面有个属性为 value,value是个集合,可以有多个ComponentScan属性,然后再......
 *
 * 【value = "com.abc" ;它的作用是扫描这个包下的,但是是否加入包含还是排斥,需要后面的代码了】
 *
 * excludeFilters:不包含过滤-->即 Filter注解上的都不加载进容器
 * includeFilters: 包含过滤---->即 Filter注解上的才会加载进容器
 * FilterType.ANNOTATION 表示注解类型的  即例如 Controller.class,Component.class ,Service.class 等等类型
 * FilterType.ASSIGNABLE_TYPE 表示指定类型的  即如我自己写的Student类型【Student.class】 StudentController类型【StudentController.class】等等
 * FilterType.ASPECTJ 表示Aspect类型的  ,几乎不用
 * FilterType.REGEX   表示满足正则表达式的,
 * FilterType.CUSTOM  表示使用自定义规则   创建实现TypeFilter实现类,若返回true,加入容器,返回false,不让加入容器
 */
/*@ComponentScans(value = {
        @ComponentScan(value = "com.abc",excludeFilters = {
                @Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
        })
})*/
/*@ComponentScans(value = {
        @ComponentScan(value = "com.abc",includeFilters = {
                @Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Student.class})
        })
})*/
@Configuration
@ComponentScans(value = {
        @ComponentScan(value = "com.abc",excludeFilters = {
                @Filter(type = FilterType.CUSTOM,classes = {myTypeFilter.class})
        },useDefaultFilters = false)
})
/**
 * 【使用第三种方式给容器导入组件使用---->>Import】
 */
@Import(Color.class)
public class myConfig {
    /**
     * @Scope作用是否是单例
     *
     * singleton:  单例的(默认值)Ioc容器启动会调用方法创建对象放到Ioc容器中,以后调用直接从容器中拿
     * prototype:  多实例的,Ioc容器并不会去调用方法创建对象放在容器中
     * request:     同意一次请求创建一个实例
     * session:     同一个Session会话
     */
    @Scope("singleton")
    @Bean
    public Student student(){
        Student student = new Student("张三", "男", 23);
        return student;
    }


    /**
     * @Conditional
     * @return
     */

    @Conditional(WindowsCondition.class)
    @Bean("bill")
    public Person person01(){
        return new Person("李四",24);
    }


    @Conditional(LinuxCondition.class)
    @Bean("linux")
    public Person person02(){
        return new Person("王五",25);
    }

    /**
     * 使用第三种方式给容器导入组件使用---->>Import
     * 1.  在配置类上加 Import(类的class对象)这是个数组,可以多个
     * 2.  还可以实现 【ImportSelector】 接口,然后在实现类添加需要加入容器的组件,注意加入的是  类的全限定名
     * 3.  还可以实现ImportBeanDefinitionRegistrar 接口:手动注册
     */


}

 【使用自定义规则】

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

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();
        //获取当前正在扫描的类的名字
        String className = classMetadata.getClassName();
    /*    if (className.contains("er")){
            System.out.println(" *********************"+className);
            return true;
        }*/
        return false;
    }
}

一:往容器中加组件的六种方式

  1.注解@Bean

  2.注解@Condition

  

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class LinuxCondition implements Condition {
    /**
     * ConditionContext :上下文信息
     * AnnotatedTypeMetadata:获取当前类注解信息
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //1 获取到Ioc使用的BeanFactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //2 获取类加载器
        ClassLoader classLoader = context.getClassLoader();
        //3 获取环境信息
        Environment environment = context.getEnvironment();
        //4 获取到Bean 定义的注册类
        BeanDefinitionRegistry registry = context.getRegistry();

        String property = environment.getProperty("os.name");
        if (property.contains("linux")){
            return true;
        }

        return false;
    }
}
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class WindowsCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //1 获取到Ioc使用的BeanFactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //2 获取类加载器
        ClassLoader classLoader = context.getClassLoader();
        //3 获取环境信息
        Environment environment = context.getEnvironment();
        //4 获取到Bean 定义的注册类
        BeanDefinitionRegistry registry = context.getRegistry();

        String property = environment.getProperty("os.name");
        if (property.contains("Windows")){
            return true;
        }
        return false;
    }
}

3.注解@Import

  4.实现 ImportSelector 接口

  5.实现 ImportBeanDefinitionRegistrar  接口

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     * AnnotationMetadata: 当前类大注解信息
     * BeanDefinitionRegistry: BeanDefinition注册类
     *           把所有需要添加到容器的中的Bean: 调用
     *           BeanDefinitionRegistry.registryBeanDefinition手工注册进来
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean red = registry.containsBeanDefinition("red");
        boolean blud = registry.containsBeanDefinition("blud");
        //如果容器中有 【red】 和【blud】两个组件,就把下面的组件加入容器
        if (red && blud){
            RootBeanDefinition beanDefinition = new RootBeanDefinition();
            //注册一个Bean,并且制定bean名称
            registry.registerBeanDefinition("raidBow",beanDefinition);
        }
    }
}

   6.实现 FactoryBean<> 接口

import com.abc.domain.Color;
import org.springframework.beans.factory.FactoryBean;

public class myFactoryBean implements FactoryBean<Color> {

    //返回一个对象,这个对象会被添加到容器中
    @Override
    public Color getObject() throws Exception {
        return new Color();
    }
    //从容器拿出组件时的类型
    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }
    //报存是否为单例 ,如果是true 就是单例,返回false就是非单例
    @Override
    public boolean isSingleton() {
        return false;
    }
}

猜你喜欢

转载自www.cnblogs.com/lcj12121/p/11434542.html