Spring注解驱动开发--注册组件

一、@Configuration、@Bean给容器中注册组件

  • 配置文件方式

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="person" class="org.hao.bean.Person">
            <property name="age" value="18"></property>
            <property name="name" value="张三"></property>
        </bean>
    
    </beans>
    
    package org.hao.bean;
    
    public class Person {
          
          
        private String name;
        private Integer age;
    
        @Override
        public String toString() {
          
          
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        public Person() {
          
          
        }
    
        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;
        }
    }
    
    package org.hao;
    
    import org.hao.bean.Person;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MainTest {
          
          
        public static void main(String[] args) {
          
          
            ClassPathXmlApplicationContext applicationContext =
                    new ClassPathXmlApplicationContext("bean.xml");
            Person bean = (Person) applicationContext.getBean("person");
            System.out.println(bean);
        }
    }
    
  • 注解方式:用配置类代替配置文件(bean.xml)

    package org.hao.config;
    /*
    配置类 == 配置文件
     */
    import org.hao.bean.Person;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration  //告诉spring这是一个配置类
    public class MainConfig {
          
          
    
        //给容器中注册一个bean;类型是返回值的类型,id默认是方法名
        @Bean("p")
        public Person person(){
          
          
            return new Person("李四", 20);
        }
    }
    
      package org.hao;
      
      import org.hao.bean.Person;
      import org.hao.config.MainConfig;
      import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      
      public class MainTest {
          
          
          public static void main(String[] args) {
          
          
              AnnotationConfigApplicationContext applicationContext =
                      new AnnotationConfigApplicationContext(MainConfig.class);
              Person bean = applicationContext.getBean(Person.class);
              System.out.println(bean);
      
              //getBeanNamesForType:查看bean组件在ioc容器中的名字。可在@Bean注解中更改
              String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
              for (String name :
                      namesForType) {
          
          
                  System.out.println(name);
              }
          }
      }
      ```
    

二、@ComponentScan自动扫描组件、指定扫描规则

  • 配置文件
    <!--  包扫描:只要标注了@Controller、@Service、@Repository、@Component  -->
        <context:component-scan base-package="org.hao" use-default-filters="false"></context:component-scan>
    
  • 配置类:在配置类中用以下配置
    @ComponentScan(value = "org.hao", includeFilters = {
          
          
            @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {
          
          Controller.class})
    }, useDefaultFilters = false)
    /**
     * @ComponentScan value:指定要扫描的包
     * excludeFilters = Filter[] : 指定扫描的时候要排除哪些组件
     * includeFilters = Filter[] : 指定只需要包含哪些组件
     */
    

三、自定义TypeFilter指定过滤规则

  • 自定义TypeFilter需要实现TypeFilter接口

    @ComponentScan(value = "org.hao", includeFilters = {
          
          
    /*        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}),
            @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {BookService.class})*/
            @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {
          
          MyTypeFilter.class})
    }, useDefaultFilters = false)
    
    /**
     * FilterType.ANNOTATION : 按照注解
     * FilterType.ASSIGNABLE_TYPE : 按照给定的类型
     * FilterType.CUSTOM : 按照自定义类型过滤
     */
    
    package org.hao.config;
    
    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 {
          
          
        /**
         *
         * @param metadataReader : 读取到的当前正在扫描的类的信息
         * @param metadataReaderFactory : 可以获取到其他任何类的信息
         * @return
         * @throws IOException
         */
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
          
          
            //获取当前正在扫描的类的类信息
            ClassMetadata classMetadata = metadataReader.getClassMetadata();
            //获取当前类注解的信息
            AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
            //获取当前的类资源(类路径)
            Resource resource = metadataReader.getResource();
    
    
            String className = classMetadata.getClassName();
            System.out.println("----->" + className);
    
            //自定义的规则
            if (className.contains("er")){
          
          
                return true;
            }
            return false;
        }
    }
    

四、@Scope设置组件作用域

  • IOC容器创建的Bean对象默认是单实例的
    @Scope(value = "singleton")//单实例 
    @Scope(value = "prototype")//多实例
    
  • singleton : IOC容器启动会调用方法创建对象饭到容器中
  • prototype : IOC容器启动并不会创建对象放在容器中,每次获取的时候才会调用方法创建对象

五、@Lazy Bean懒加载

  • @Lazy:懒加载/延迟加载
  • 单实例Bean:默认在容器启动时创建对象
  • 懒加载:容器启动不会创建对象,第一次使用时创建
    @Lazy
    

六、@Conditional按照条件注册Bean

  • 按照一定的条件进行判断,满足条件就给容器中注册Bean
@Conditional({
    
    要传入的判断条件})

在这里插入图片描述

七、@Import快速导入组件

  • 容器中注册组件的方法:
  1. 包扫描+组件标注注解(@Controller、@Service、@Repository、@Component)
  2. @Bean(导入第三方包里的组件)
  3. @Import(快速给容器导入一个组件)
    1. @Import(要导入到容器中的组件):容器中会自动注册这个组件,id默认是全类名
      @Import({
              
              Color.class, Red.class})
      
    2. ImportSelector:返回需要导入的组件的全类名数组
      在这里插入图片描述
    3. ImportBeanDefinitionRegistrar:手动注册Bean到容器中
      在这里插入图片描述

八、使用FactoryBean注册组件

  • 工厂模式
    package org.hao.bean;
    
    import org.springframework.beans.factory.FactoryBean;
    
    //创建一个Spring定义的FactoryBean
    public class ColorFactoryBean implements FactoryBean<Color> {
          
          
        //返回一个Color对象,这个对象会添加到容器中
        public Color getObject() throws Exception {
          
          
            return new Color();
        }
    
        //对象类型
        public Class<?> getObjectType() {
          
          
            return Color.class;
        }
    
        public boolean isSingleton() {
          
          
            return false;
        }
    }
    
    
    //在配置类中注册
    @Bean
        public ColorFactoryBean colorFactoryBean(){
          
          
            return new ColorFactoryBean();
        }
    

猜你喜欢

转载自blog.csdn.net/weixin_44863537/article/details/108759587