Spring 纯注解开发--001--基本注解学习

本文深入探讨Spring框架的高级配置技巧,包括自定义类型扫描过滤器、条件化Bean注册及懒加载实现。通过实例演示如何精确控制类扫描,实现基于环境的Bean条件注册,以及懒加载优化单实例Bean的创建时机。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@Bean
@Configuration
@ConponentScans
  • 使用自己的类型扫描过滤器,来实现对固定的类进行扫描
  • 案例实现
    • 扫描com.learning包中的注解,只有符合过滤条件MyTypeFilter,才可以加入到容器中
    • 因为spring默认扫描指定包下的所有内容,如果做过滤条件,必须将默认的扫描过滤关掉,即useDefaultFilters=false
/**
* 配置类
*/
@Configuration
@ComponentScans({
        @ComponentScan(value = "com.learning",includeFilters = {
                @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
        },useDefaultFilters = false)
})
public class MyConfig {

    @Bean
    public Person person(){
        return new Person("小明",11);
    }


    @Bean(name = "xiaoming")
    public Person person1(){
        return new Person("xiaoming",23);
    }
}
/**
*扫描类
*/
public class MyTypeFilter implements TypeFilter {

    //metadataReader  当前扫描到的所有类的信息
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {

        //获取当前扫描类注解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        System.out.println("++++++"+annotationMetadata.getClass());

        //获取当前正在扫描类的信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        System.out.println("-------"+classMetadata.getClassName());

        //获取当前正在扫描类的路径
        Resource resource = metadataReader.getResource();
        System.out.println("------"+resource);

        //返回为true表示可以扫描通过,否则扫描失败,不加入到spring容器中
        if(classMetadata.getClassName().contains("ser")){
            return  true;
        }
        return false;
    }
}
@Scope
  • 用来声明单实例、多实例
  • 创建时机
    • singleton:单实例,IOC容器启动会调用方法创建对象放到IOC容器中,以后每次获取就是直接从容器中获得
    • prototype:多实例,IOC启动不会调用方法创建对象放到容器,而是在每次获取的时候才会调用方法创建对象放到IOC容器中。
@Lazy
  • 作用:实现懒加载功能
  • 作用范围:针对单实例对象
@Conditional
  • spring4.0之后提供的
  • 作用:按照一定的条件进行判断,满足条件给容器中注册bean
  • 使用@Conditional(Condition)
  • 事例
    • 实现功能,在windons环境下,注入bill gate的Person,在Linux环境下,注入linus的Person
//配置类
@Configuration

//类上的优先级更高,相当于类都没有通过,更不用说方法,可以形象的比喻,第一层关卡都没有通过,没有资格进入第二个关卡
//对类中进行统一设置
@Conditional(LinuxCondition.class)
public class MyConfig_Conditional {


    /**
     *  如果是windons系统,往容器中放 id = bill 的Person
     *  如果是linux系统 ,往容器中放  id = linus 的Person
     */
    @Conditional(WindowsCondition.class)
    @Bean("bill")
    public Person person(){
        return new Person("Bill Gates",11);
    }


    @Conditional(LinuxCondition.class)
    @Bean(name = "linus")
    public Person person1(){
        return new Person("Linus",23);
    }
}
//对象类
public class Person {

    private String name;

    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
//条件类  Condition

//windons下的条件
public class WindowsCondition implements Condition {

    /**
     * @param conditionContext 判断条件能使用的上下文
     * @param annotatedTypeMetadata 当前注解信息
     * @return
     */
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {

        //获取工厂
        ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();

        //获取类加载器
        ClassLoader classLoader = conditionContext.getClassLoader();

        //获取bean定义的注册类
        BeanDefinitionRegistry registry = conditionContext.getRegistry();

        //通过registry可以判断容器中bean的注册情况,也可以给容器中注册bean
        //判断是否已经注册了person的bean
        boolean person = registry.containsBeanDefinition("person");

        //获取环境信息
        Environment environment = conditionContext.getEnvironment();
        String property = environment.getProperty("os.name");
        return property.toLowerCase().contains("window");
    }
}
//linux下的条件
public class LinuxCondition implements Condition {

    /**
     * @param conditionContext 判断条件能使用的上下文
     * @param annotatedTypeMetadata 当前注解信息
     * @return
     */
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {

        Environment environment = conditionContext.getEnvironment();
        String property = environment.getProperty("os.name");
        return property.toLowerCase().contains("linux");
    }
}
//测试类
public class Test {
    static AnnotationConfigApplicationContext applicationContext = null;
    static{
        applicationContext =
                new AnnotationConfigApplicationContext(MyConfig_Conditional.class);
    }

    public static void main(String[] args) {
        test_Conditional();
    }

    //测试@Conditional注解
    public static void test_Conditional(){

        //获取操作系统
        Map<String, Person> beansOfType = applicationContext.getBeansOfType(Person.class);
        beansOfType.forEach((str,p)-> System.out.println(p));
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值