Spring常用注解-Bean注册(一)


在如今Spring Boot、Spring Cloud的兴起,Spring注解开发已成为主流开发模式。本篇将介绍常用的组件注册方式。

环境准备

新建Maven项目,添加依赖

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.26.RELEASE</version>
    </dependency>
</dependencies>

1、@Configuration @Bean

新增Person类

public class Person {
    private String name;
    private Integer age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

新增config类

@Configuration
public class ApplicationConfig {

 	/*
    默认name是获取Bean的方法名  person
    @Bean("person001") 这样使用注解  name则为person001
     */
    @Bean
    public Person person(){
        return new Person("小符",18);
    }

}

获取Bean

public class Application {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
        Object person = context.getBean("person");
        System.out.println(person);
    }
}

输出
在这里插入图片描述

2、@ComponentScan

自动扫描包方式
扫描如下注解:

  1. @Controller
  2. @Service
  3. @Repository
  4. @Component

在bean下新建一个类并加上@Component注解表示将该Bean注册到容器中

@Component
public class Animal {
}

在Config类中加入注解

@Configuration
@ComponentScan("com.fred.bean")
public class ApplicationConfig {

    /*
    默认name是获取Bean的方法名  person
    @Bean("person001") 这样使用注解  name则为person001
     */
    @Bean
    public Person person(){
        return new Person("小符",18);
    }

}

@ComponentScan注解加上 value:com.fred.bean表示扫描这个包下的Bean(前提是Bean上有注解@Controller、@Service、@Repository、@Component 中的其中一个)才能被扫描到。

输出当前容器容器中的存在的Bean的name

public class Application {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
//        Object person = context.getBean("person");
//        System.out.println(person);
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
    }
}

输出
在这里插入图片描述
可以看到,除了Spring自己注册的Bean,以及之前注入的Bean,刚刚加入的Animal也存在容器中了。

	@ComponentScan也可以不写参数,则默认扫描的是当前注解的类的包下。
	例如@ComponentScan注解的是ApplicationConfig类com.fred.config.ApplicationConfig
	则等同于@ComponentScan("com.fred.config")的效果
2.1 、使用FilterType指定扫描过滤规则

有以下几种方式实现过滤

public enum FilterType {
    ANNOTATION,//注解
    ASSIGNABLE_TYPE,//类型
    ASPECTJ,//ASPECT表达式
    REGEX,//正则表达式
    CUSTOM;//自定义

    private FilterType() {
    }
}

默认是 ANNOTATION

excludeFilters

excludeFilters的作用是排除过滤

@Configuration
@ComponentScan(value = "com.fred.bean",excludeFilters = {
        @ComponentScan.Filter(Service.class)
})
public class ApplicationConfig {

    /*
    默认name是获取Bean的方法名  person
    @Bean("person001") 这样使用注解  name则为person001
     */
    @Bean
    public Person person(){
        return new Person("小符",18);
    }

}

排除Service注解的Bean
修改Inner类注解为@Service

@Service
public class Inner {
}

输出当前容器容器中的存在的Bean的name
在这里插入图片描述
可以看到Inner就被排除了。

使用ASSIGNABLE_TYPE方式

@Configuration
@ComponentScan(value = "com.fred.bean",excludeFilters = {
        //Filter默认是   FilterType.ANNOTATION
        //@ComponentScan.Filter(Service.class)
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Inner.class})
})
public class ApplicationConfig {

    /*
    默认name是获取Bean的方法名  person
    @Bean("person001") 这样使用注解  name则为person001
     */
    @Bean
    public Person person(){
        return new Person("小符",18);
    }

}

输出当前容器容器中的存在的Bean的name
在这里插入图片描述
InnerBean就被排除了。

使用CUSTOM方式
自定义需要实现TypeFilter接口

public class MyFilterType implements TypeFilter {
    /*
    参数:
    annotationMetadata      可以获取到扫描到Bean的注解相关信息   Class相关信息    资源信息等
    metadataReaderFactory   可以获取父类、接口等
    返回值True表示要排除     false则不排除
     */
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        System.out.println(metadataReader.getClassMetadata().getClassName());
        //如果是Animal就排除
        if (metadataReader.getClassMetadata().getClassName().equals("com.fred.bean.Animal")) {
            return true;
        }
        //其他都不排除
        return false;
    }
}

输出当前容器容器中的存在的Bean的name
在这里插入图片描述
可以看到Animal被排除了。

includeFilters

includeFilters和excludeFilters用法大同小异,作用是包含。

需要注意的是@ComponentScan的useDefaultFilters默认为Ture表示会自动扫描 @Component、@Repository、 @Service、@Controller,为True的情况下设置includeFilters只包含@Controller注解的Bean,@Component、@Repository、 @Service也会被自动扫描到。根据需求需要可设置为False。

项目结构
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值