一、Spring

1、容器——组件注册

1、 @Configuration 注解& @Bean 注解

@Configuration :一般修饰在一个类上,告诉Spring容器这是一个配置类。

其实我们最开始学习Spring的时候,是通过创建一个 xml 文件,通过 bean 标签来注册bean的,如下,我们新建了一个 Person 实体类,然后新建 beans.xml 注册一个 Person 实例到 bean 容器中:

Person.java

  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. @ToString
  5. public class Person {
  6. private String name;
  7. private Integer age;
  8. }

beans.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. https://www.springframework.org/schema/context/spring-context.xsd">
  9. <bean id="person" class="com.ftj.bean.Person">
  10. <property name="name" value="ftj"/>
  11. <property name="age" value="18"/>
  12. </bean>
  13. </beans>

测试类:MainTest.java

  1. public class MainTest {
  2. @Test
  3. public void test() {
  4. ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
  5. Person person = (Person) context.getBean("person");
  6. System.out.println(person);
  7. }
  8. }

image.png如上,通过ClassPathXmlApplicationContext加载配置文件,加载到 Spring 应用上下文,获取bean实例,即可得到刚才注册的 idpersonbean 实例。

而现在我们可以通过 @Configuration 注解和 @bean 注解去给容器注册组件,如下:只需要新建一个配置类 MainConfig.java (名字随意),里面创建一个返回值类型为所需注册组件类型的方法即可。

  1. //配置类==配置文件
  2. @Configuration //告诉spring这是一个配置类
  3. public class MainConfig {
  4. @Bean("person") //给容器中注册一个Bean;类型:返回值类型 id:默认方法名为id
  5. public Person getPerson() {
  6. return new Person("lisi", 20);
  7. }
  8. }

此处:可以通过给 @bean 注解,设置组件的名称(如果不设置,默认是方法名作为bean组件名称),效果类似与配置文件形式的 bean 标签内的 id

  1. public class MainTest {
  2. @Test
  3. public void test2() {
  4. ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
  5. Person getPerson = (Person) context.getBean("person");
  6. System.out.println(getPerson);
  7. //获取Person类型的bean的名字
  8. String[] beanNamesForType = context.getBeanNamesForType(Person.class);
  9. for (String s : beanNamesForType) {
  10. System.out.println(s);
  11. }
  12. }
  13. }

image.png
效果跟配置文件形式获取bean是一样的,这里要注意的是,注解方式是通过 AnnotationConfigApplicationContext 来加载 Spring 应用的上下文的。

注意:这里可以使用 getBeanNamesForType 方法,传递某个类型,即可以查看该类型在bean容器中,有哪些组件,如上例,我们通过 @Bean 注解注册了名为 person 的组件,那么遍历下结果,就为如下:
image.png

2、 @ComponentScan 自动扫描组件&指定扫描组件

@ComponentScan 注解用来扫描组件并且注册(可以指定需要扫描的组件)。

在原来我们使用 XML 方式开发的时候,我们需要通过 context:component-scan 标签的 base-package 属性来指定需要扫描的组件,如下:

  1. <context:component-scan base-package="com.ftj" use-default-filters="true"></context:component-scan>

use-default-filters 属性默认 true ,如果是 fasle 那么则是,禁用默认的扫描规则(默认一般扫描 @Component @Service @Repository @Controller 注解),自己指定扫描规则,可以使用 context:include-filter 标签来指定:

  1. <!-- 配置自动扫描的包 -->
  2. <context:component-scan base-package="" use-default-filters="false">
  3. <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>//只扫描@Controller
  4. </context:component-scan>

excludeFilters = Filter[] :指定扫描的时候按照什么规则排除哪些组件。 includeFilters = Filter[]:指定扫描的时候只需要包含哪些组件。

现在我们可以再主配置类上,使用@ComponentScan注解来指定要扫描的包,如下:

  1. @ComponentScan(value = "com.ftj", includeFilters = {
  2. @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})
  3. }, useDefaultFilters = false)

includeFiltersFilter 一起使用是用来指定需要扫描的包,如上,说明只需要扫描 @Controller@Service 注解下的类,而禁用默认规则则可以使用 useDefaultFiltersfalse

而且我们可以通过查看源码发现,还可以通过其他的规则进行排除:如根据类型 ASSIGNABLE_TYPE (如果排除的是User.class,那么其子类,实现类的都会被排除),
ASPECTJREGEX 正则, CUSTOM

image.png

也可以这么玩:

  1. @ComponentScans(value = {
  2. @ComponentScan(value = "com.ftj", includeFilters = {
  3. @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})
  4. }, useDefaultFilters = false)
  5. })

@ComponentScans 注解中使用 value 可以放多个 @ComponentScan

image.png