1. @Bean:类注入容器

    1. xml方式:

      <bean id="person" class="com.hrh.bean.Person">
      <property name="name" value="张三"></property>
      <property name="age" value="20"></property>
      </bean>
      public static void main(String[] args) {
      ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
      Person person = (Person) context.getBean("person");
      System.out.println(person);
      }
    2. @Bean+@Configuration方式:
      @Configuration//配置类==配置文件
      public class BeanConfig {
      @Bean
      public Person person(){
      return new Person("张三",20);
      }
      }
      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
      Person person = (Person)context.getBean("person"); 
  2. @ComponentScan:扫描类注入容器

    1. xml方式:

      <!-- component-scan包扫描,只要标注了@Controller、@Service、@Repository、@Component的类会注入容器中
      use-default-filters=false禁用默认过滤规则,使用自定义过滤规则
      -->
      <context:component-scan base-package="com.hrh" use-default-filters="false"/>
    2. @ComponentScan方式:JDK1.8的ComponentScan是Repeatable的,即可以在类上定义多个@ComponentScan
      @Configuration//配置类==配置文件
      /**
      * value:指定要扫描的包
      * includeFilters:指定扫描时只需要包含哪些组件,需要使用useDefaultFilters = false使规则生效
      * excludeFilters:指定扫描时按照什么规则排除哪些组件
      */
      @ComponentScan(value = "com.hrh",includeFilters = {
      @Filter(type = FilterType.ANNOTATION,
      classes = {Controller.class})
      },useDefaultFilters = false)
      public class BeanConfig {
      @Bean
      public Person person(){
      return new Person("张三",20);
      }
      }
      //====结果====
      org.springframework.context.annotation.internalConfigurationAnnotationProcessor
      org.springframework.context.annotation.internalAutowiredAnnotationProcessor
      org.springframework.context.annotation.internalCommonAnnotationProcessor
      org.springframework.context.event.internalEventListenerProcessor
      org.springframework.context.event.internalEventListenerFactory
      beanConfig
      userController
      person
    3. @ComponentScans:如果不是JDK1.8,可以使用该注解定义多个@ComponentScan
      @ComponentScans({
      @ComponentScan(value = "com.hrh",includeFilters = {
      @ComponentScan.Filter(type = FilterType.ANNOTATION,
      classes = {Controller.class})
      },useDefaultFilters = false)
      })
      public class BeanConfig {
      @Bean
      public Person person(){
      return new Person("张三",20);
      }
      }
    4. @Filter:过滤规则
      @Configuration//配置类==配置文件
      /**
      * FilterType.ANNOTATION:根据注解扫描指定的类
      * FilterType.ASSIGNABLE_TYPE:按照给定的类型,如果是接口类型,其实现类和子类注入容器;如果是类,本类和子类注入容器
      * FilterType.ASPECTJ:使用ASPECTJ表达式
      * FilterType.REGEX:使用正则表达式
      * FilterType.CUSTOM:使用自定义规则,自定义实现TypeFilter接口,重写match方法
      */
      @ComponentScan(value = "com.hrh", includeFilters = {
      // @ComponentScan.Filter(type = FilterType.ANNOTATION,
      // classes = {IUserService.class}),
      // @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
      // classes = {IUserService.class}),
      @ComponentScan.Filter(type = FilterType.CUSTOM,classes ={MyTypeFilter.class} )
      }, useDefaultFilters = false)
      public class BeanConfig {
      @Bean
      public Person person() {
      return new Person("张三", 20);
      }
      } public class MyTypeFilter implements TypeFilter {
      /**
      *
      * @param metadataReader 读取到的当前正在扫描的类的信息
      * @param metadataReaderFactory 可以获取到其他任何类的信息
      * @return ture则将类加入容器
      * @throws IOException
      */
      public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
      //获取当前类注解的信息
      AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
      //获取当前类资源(类路径)
      Resource resource = metadataReader.getResource();
      //获取当前正在扫描的类的类信息
      ClassMetadata classMetadata = metadataReader.getClassMetadata();
      String className = classMetadata.getClassName();
      System.out.println("className:"+className);
      if(className.contains("Controller")){
      return true;
      }
      return false;
      }
      }
      //====结果====
      className:com.hrh.bean.Person
      className:com.hrh.config.MyTypeFilter
      className:com.hrh.controller.UserController
      className:com.hrh.dao.UserDao
      className:com.hrh.service.IUserService
      className:com.hrh.service.SubUserService
      className:com.hrh.service.UserService
      org.springframework.context.annotation.internalConfigurationAnnotationProcessor
      org.springframework.context.annotation.internalAutowiredAnnotationProcessor
      org.springframework.context.annotation.internalCommonAnnotationProcessor
      org.springframework.context.event.internalEventListenerProcessor
      org.springframework.context.event.internalEventListenerFactory
      beanConfig
      userController
      person
  3. @Scope:作用域

    @Configuration
    @ComponentScan(value = "com.hrh")
    public class BeanConfig {
    /**
    * ConfigurableBeanFactory#SCOPE_PROTOTYPE:prototype
    * ConfigurableBeanFactory#SCOPE_SINGLETON:singleton
    * org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST:request
    * org.springframework.web.context.WebApplicationContext#SCOPE_SESSION:session
    * prototype:多实例,只有在获取的时候才会注入容器,每次获取都会进行创建对象注入不同的实例,每次获取的对象都不同
    * singleton:单实例(默认值),ioc容器启动会调用该方法创建对象注入容器,每次获取直接中容器中拿
    * request:同一次请求创建一个实例
    * session:同一个session创建一个实例
    */ @Scope(value = "prototype")
    @Bean
    public Person person() {
    System.out.println("注入容器。。。。。");
    return new Person("张三", 20);
    }
    • @Lazy:懒加载,项目启动时不创建对象注入容器,只在第一次调用时才创建对象并初始化

          @Lazy
      @Bean
      public Person person() {
      System.out.println("注入容器。。。。。");
      return new Person("张三", 20);
      }
  4. @Conditional:按照条件注入容器,实现Condition的matches()

    @Configuration
    @ComponentScan(value = "com.hrh")
    public class BeanConfig {
    @Conditional(WindowsConfig.class)
    @Bean(value = "Bill")
    public Person person1() {
    System.out.println("创建Windows。。。。。");
    return new Person("Bill", 20);
    }
    @Conditional(LinuxConfig.class)
    @Bean(value = "Linux")
    public Person person2() {
    System.out.println("创建Linux。。。。。");
    return new Person("Linux", 20);
    }
    }
    public class WindowsConfig implements Condition {
    /**
    *
    * @param context 判断条件能使用的上下文
    * @param metadata 注释信息
    * @return
    */
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    //获取ioc使用的beanFactory
    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    //获取类加载器
    ClassLoader classLoader = beanFactory.getBeanClassLoader();
    Environment environment = context.getEnvironment();
    String property = environment.getProperty("os.name");
    if("Windows 10".equals(property)){
    return true;//当前系统环境是windows 10,将条件下的bean注入容器
    }
    return false;
    }
    }
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    //获取ioc使用的beanFactory
    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    //获取类加载器
    ClassLoader classLoader = beanFactory.getBeanClassLoader();
    Environment environment = context.getEnvironment();
    String property = environment.getProperty("os.name");
    if("Linux".equals(property)){
    return true;
    }
    return false;
    }
  5. @Import:快速导入组件进容器

    public class Color {
    }
    @Configuration
    @ComponentScan(value = "com.hrh")
    @Import(Color.class)
    //@Import({Color.class,Person.class})导入多个
    public class BeanConfig {}
    public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
    String[] beanDefinitionNames = context.getBeanDefinitionNames();
    for(String beanName:beanDefinitionNames){
    System.out.println(beanName);
    }
    }
    1. ImportSelector:实现该接口,重写selectImports()

      public class MyImportSelector implements ImportSelector {
      /**
      *
      * @param importingClassMetadata 当前标注@Import的类的全部注解信息,比如该类还标注了@Configuration也会被获取到
      * @return 返回的组件全类名加入到容器中
      */
      public String[] selectImports(AnnotationMetadata importingClassMetadata) {
      return new String[]{"com.hrh.bean.Color","com.hrh.bean.Person"};
      }
      } @Configuration
      @ComponentScan(value = "com.hrh")
      @Import({MyImportSelector.class})
      public class BeanConfig {}
    2. ImportBeanDefinitionRegistrar:实现ImportBeanDefinitionRegistrar,重写registerBeanDefinitions()

      @Configuration
      @Import({Color.class,MyImportBeanDefinitionRegistrar.class})
      public class BeanConfig {}
      public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
      /**
      *
      * @param importingClassMetadata 当前类的注解信息
      * @param registry BeanDefinition注册类,把所有需要添加到容器中的bean,调用BeanDefinitionRegistryregisterBeanDefinition注册进来
      */
      @Override
      public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
      boolean color = registry.containsBeanDefinition("com.hrh.bean.Color");
      //容器中有Color类才将Person类进行注入
      if(color) {
      RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Person.class);
      registry.registerBeanDefinition("person",rootBeanDefinition);
      } }
  6. FactoryBean

    public class MyFactoryBean implements FactoryBean<Color> {
    //返回一个对象,并且该对象会注入容器
    @Override
    public Color getObject() throws Exception { return new Color();
    } @Override
    public Class<?> getObjectType() {
    return Color.class;
    } @Override
    public boolean isSingleton() {
    return true;
    }
    }
    @Configuration
    public class BeanConfig {
    /**
    * 1.默认获取的是MyFactoryBean调用getObject创建的对象
    * 2.要获取MyFactoryBean本身,需要给id前加&,比如&myBeanFactory
    */
    @Bean
    public MyFactoryBean myBeanFactory(){
    return new MyFactoryBean();
    }
    }
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
    Object bean1=context.getBean("myBeanFactory");
    System.out.println(bean1.getClass());
    Object bean2=context.getBean("&myBeanFactory");
    System.out.println(bean2.getClass());

Spring笔记 - 组件注册的更多相关文章

  1. Spring Framework 组件注册 之 @Component

    Spring Framework 组件注册 之 @Component 写在前面 在spring大行其道的今天,对于spring的使用和掌握乃是不可缺少的必备技能.但是spring的整个体系尤为庞大,对 ...

  2. Spring Framework 组件注册 之 @Import

    Spring Framework 组件注册 之 @Import 写在前面 向spring中注册组件或者叫javaBean是使用spring的功能的前提条件.而且spring也提供了很多种方式,让我们可 ...

  3. Spring Framework 组件注册 之 FactoryBean

    Spring Framework 组件注册 之 FactoryBean 前言 前两篇文章介绍了如何使用@Component,@Import注解来向spring容器中注册组件(javaBean),本文将 ...

  4. spring注解-组件注册

    一.@Configuration+@Bean @Configuration:配置类==配置文件 @Bean:给容器中注册一个Bean:类型为返回值的类型,默认是用方法名作为id @Bean(" ...

  5. 一、Spring之组件注册-@Configuration&@Bean给容器中注册组件

    xml配置方式 首先我们创建一个实体类Person public class Person { private String name; private Integer age; private St ...

  6. 【建议收藏】阿里P7总结的Spring注解笔记,把组件注册讲的明明白白

    环境搭建 注解的方式是通过配置类的方式来注入组件,注解注入要比XML注入的方式简单,注解注入也需要在前者的基础上,添加一个spring-context的包,也是实际开发中常用的方式. 准备所需Jar包 ...

  7. spring注解扫描组件注册

    最近对单点系统进行微服务拆分,被各个springboot的组件注册搞得云里雾里的.(有的是通过springboot的自动配置进IOC容器的,有的是自己添加构造方法添加进IOC容器.)决定抽时间将spr ...

  8. 【spring 注解驱动开发】spring组件注册

    尚学堂spring 注解驱动开发学习笔记之 - 组件注册 组件注册 1.@Configuration&@Bean给容器中注册组件 2.@ComponentScan-自动扫描组件&指定扫 ...

  9. 向Spring容器中注册组件的方法汇总小结

    1.通过xml定义 <bean class=""> <property name="" value=""></ ...

随机推荐

  1. Knapsack Problem

    0-1背包 描述:N件物品,第i件的重量是w[i],价值v[i].有一个容量为W的背包,求将哪些物品放入背包可使总价值最大.每件物品可以用0或1次. 分析:根据题意,可以写出表达式: \[max(\S ...

  2. ACM-ICPC 2019 山东省省赛 C Wandering Robot

    这个题额,我觉的是一道水题,思维题,需要考虑的情况比较多,题意一个机器人给一条指令,循环n遍,问此过程中离原点最远距离. 考虑最远距离可能出现的的情况. 每次循环之后距离至少为0: 1.假设他每一次循 ...

  3. js递归实现方式

    定义: 递归函数就是在函数体内调用本函数: 递归函数的使用要注意函数终止条件避免死循环: 递归实现形式: 1.声明一个具名函数,通过函数名调用 function f(a){ if(a<=1){ ...

  4. vue-infinite-scroll------vue的无线滚动插件

    vue-infinite-scroll------vue的无线滚动插件 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 说明 V ...

  5. java结合email实现自动推送

    1.获取表中最后一条数据 public static String demo() throws SQLException { String sql = "select * FROM baox ...

  6. Android 8.1 关机充电动画(二)Uboot模式

    system:Android 8.1 platform:RK3326/PX30 uboot kernel Android 8.1 关机充电动画(一)模式选择 Android 8.1 关机充电动画(二) ...

  7. ASP.NET 开源导入导出库Magicodes.IE 完成Csv导入导出

    Magicodes.IE Csv导入导出 说明 本章主要说明如何使用Magicodes.IE.Csv进行Csv导入导出. 主要步骤 1.安装包Magicodes.IE.Csv Install-Pack ...

  8. iview tree 绑定数据

    官方文档 :https://www.iviewui.com/components/tree 效果图 1 主体分析 <Tree ref="tree" :data="t ...

  9. 给bootstrap右边的菜单加上右键关闭

    <ul class="rightmenu"> <li data-type="closethis">关闭当前</li> < ...

  10. 【5min+】美化API,包装AspNetCore的返回结果

    系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...