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

Posted alimayun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring注解驱动开发-----组件注册相关的知识,希望对你有一定的参考价值。

注册bean

xml方式

1、beans.xml-----很简单,里面注册了一个person 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"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

    <bean id="person" class="com.atguigu.bean.Person">
        <property name="age" value="18"></property>
        <property name="name" value="zhangsan"></property>
    </bean>
</beans>

2、person

package com.atguigu.bean;

import org.springframework.beans.factory.annotation.Value;

public class Person 
private String name;
private Integer 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;
    
    
    public Person(String name, Integer age) 
        super();
        this.name = name;
        this.age = age;
    
    public Person() 
        super();
    
    @Override
    public String toString() 
        return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]";
    

3、MainTest-----测试类

package com.atguigu;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.atguigu.bean.Person;
import com.atguigu.config.MainConfig;

public class MainTest 
    
    @SuppressWarnings("resource")
    public static void main(String[] args) 
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        Person bean = (Person) applicationContext.getBean("person");
        System.out.println(bean);

测试结果:

技术图片

注解方式

 1、MainConfig-----配置类

@Configuration  //告诉Spring这是一个配置类
    //给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person")
    public Person person01()
        return new Person("lisi", 20);
    

2、MainTest

package com.atguigu;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.atguigu.bean.Person;
import com.atguigu.config.MainConfig;

public class MainTest 
    
    @SuppressWarnings("resource")
    public static void main(String[] args) 
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        Person bean = applicationContext.getBean(Person.class);
        System.out.println(bean);
        
        String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
        for (String name : namesForType) 
            System.out.println(name);
        
    

3、@Configuration-----可以看出是继承了@Component

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration 
    @AliasFor(annotation = Component.class)
    String value() default "";

自动扫描

xml方式 

1、beans.xml 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
    <context:component-scan base-package="com.atguigu"></context:component-scan>
    <bean id="person" class="com.atguigu.bean.Person">
        <property name="age" value="18"></property>
        <property name="name" value="zhangsan"></property>
    </bean>
</beans>

注解方式

1、MainConfig

package com.atguigu.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.ComponentScans;

import com.atguigu.bean.Person;

//配置类==配置文件
@Configuration  //告诉Spring这是一个配置类
@ComponentScan(value="com.atguigu")  //value:指定要扫描的包
public class MainConfig     
    //给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person")
    public Person person01()
        return new Person("lisi", 20);
    

2、BookController

package com.atguigu.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.atguigu.service.BookService;

@Controller
public class BookController 
    
    @Autowired
    private BookService bookService;

3、BookService

package com.atguigu.service;


import javax.annotation.Resource;
import javax.inject.Inject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.atguigu.dao.BookDao;


@Service
public class BookService 

    @Autowired(required=false)
    private BookDao bookDao;
    
    public void print()
        System.out.println(bookDao);
    

    @Override
    public String toString() 
        return "BookService [bookDao=" + bookDao + "]";
    

4、BookDao

package com.atguigu.dao;

import org.springframework.stereotype.Repository;

//名字默认是类名首字母小写
@Repository
public class BookDao 
    
    private String lable = "1";

    public String getLable() 
        return lable;
    

    public void setLable(String lable) 
        this.lable = lable;
    

    @Override
    public String toString() 
        return "BookDao [lable=" + lable + "]";
    

5、IocTest

package com.atguigu.test;

import java.util.Map;

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

import com.atguigu.bean.Blue;
import com.atguigu.bean.Person;
import com.atguigu.config.MainConfig;
import com.atguigu.config.MainConfig2;

public class IOCTest 
    
    @SuppressWarnings("resource")
    @Test
    public void test01()
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] definitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : definitionNames) 
            System.out.println(name);
        
    

@ComponentScan

1、excludeFilters

@ComponentScan(value="com.atguigu",excludeFilters = 
                        @Filter(type=FilterType.ANNOTATION,classes=Controller.class,Service.class))

排除controller以及service,不允许注册。

2、includeFilters

@ComponentScan(value="com.atguigu",includeFilters = 
                        @Filter(type=FilterType.ANNOTATION,classes=Controller.class),useDefaultFilters=false)

只扫描controller。-----需要添加useDefaultFilters=false

@ComponentScans 

@ComponentScans(
        value = 
                @ComponentScan(value="com.atguigu",includeFilters = 
                        @Filter(type=FilterType.ANNOTATION,classes=Controller.class)
                ,useDefaultFilters = false)    
        
        )

其实就是可以定义多个扫描策略。

TypeFilter 

  • @ComponentScan value:指定要扫描的包
  • excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
  • includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
  • FilterType.ANNOTATION:按照注解
  • FilterType.ASSIGNABLE_TYPE:按照给定的类型;
  • FilterType.ASPECTJ:使用ASPECTJ表达式
  • FilterType.REGEX:使用正则指定
  • FilterType.CUSTOM:使用自定义规则

其中注解最为常见。 

设置组件作用域

@Scope

 spring中默认都是单例bean,不过也可以通过@Scope进行设置。

1、MainConfig2

package com.atguigu.config;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

import com.atguigu.bean.Blue;
import com.atguigu.bean.Color;
import com.atguigu.bean.ColorFactoryBean;
import com.atguigu.bean.Person;
import com.atguigu.bean.Red;
import com.atguigu.condition.LinuxCondition;
import com.atguigu.condition.MyImportBeanDefinitionRegistrar;
import com.atguigu.condition.MyImportSelector;
import com.atguigu.condition.WindowsCondition;
import com.atguigu.test.IOCTest;

@Configuration
public class MainConfig2 
    
    //默认是单实例的
    /**
     * ConfigurableBeanFactory#SCOPE_PROTOTYPE    
     * @see ConfigurableBeanFactory#SCOPE_SINGLETON  
     * @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST  request
     * @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION     sesssion
     * @return     * @Scope:调整作用域
     * prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
     *                     每次获取的时候才会调用方法创建对象;
     * singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
     *             以后每次获取就是直接从容器(map.get())中拿,
     * request:同一次请求创建一个实例
     * session:同一个session创建一个实例
     */
    @Scope("prototype")
    @Bean("person")
    public Person person()
        System.out.println("给容器中添加Person....");
        return new Person("张三", 25);
    

2、IocTest

package com.atguigu.test;

import java.util.Map;

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

import com.atguigu.bean.Blue;
import com.atguigu.bean.Person;
import com.atguigu.config.MainConfig;
import com.atguigu.config.MainConfig2;

public class IOCTest 
    
    @Test
    public void test02()
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);

        System.out.println("ioc容器创建完成....");
        Object bean = applicationContext.getBean("person");
        Object bean2 = applicationContext.getBean("person");
        System.out.println(bean == bean2);
    

3、测试结果

技术图片

@Lazy-----只针对于singleton模式

package com.atguigu.config;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

import com.atguigu.bean.Blue;
import com.atguigu.bean.Color;
import com.atguigu.bean.ColorFactoryBean;
import com.atguigu.bean.Person;
import com.atguigu.bean.Red;
import com.atguigu.condition.LinuxCondition;
import com.atguigu.condition.MyImportBeanDefinitionRegistrar;
import com.atguigu.condition.MyImportSelector;
import com.atguigu.condition.WindowsCondition;
import com.atguigu.test.IOCTest;

@Configuration
public class MainConfig2 
    
    //默认是单实例的
    /**
     * 懒加载:
     *         单实例bean:默认在容器启动的时候创建对象;
     *         懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
     * 
     */
    @Scope("singleton")
    @Lazy
    @Bean("person")
    public Person person()
        System.out.println("给容器中添加Person....");
        return new Person("张三", 25);
    

@Conditional-----按照一定的条件进行判断,满足条件给容器中注册bean

配置在方法上

示例:根据是windows还是linux系统,判断person为Bill还是Linus

1、MainConfig

package com.atguigu.config;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

import com.atguigu.bean.Blue;
import com.atguigu.bean.Color;
import com.atguigu.bean.ColorFactoryBean;
import com.atguigu.bean.Person;
import com.atguigu.bean.Red;
import com.atguigu.condition.LinuxCondition;
import com.atguigu.condition.MyImportBeanDefinitionRegistrar;
import com.atguigu.condition.MyImportSelector;
import com.atguigu.condition.WindowsCondition;
import com.atguigu.test.IOCTest;

@Configuration
public class MainConfig2 

    /**
     * @Conditional(Condition) : 按照一定的条件进行判断,满足条件给容器中注册bean
     * 
     * 如果系统是windows,给容器中注册("bill")
     * 如果是linux系统,给容器中注册("linus")
     */
    @Conditional(WindowsCondition.class)
    @Bean("bill")
    public Person person01()
        return new Person("Bill Gates",62);
    
    
    @Conditional(LinuxCondition.class)
    @Bean("linus")
    public Person person02()
        return new Person("linus", 48);
    

2、LinuxCondition

package com.atguigu.condition;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

//判断是否linux系统
public class LinuxCondition implements Condition 

    /**
     * ConditionContext:判断条件能使用的上下文(环境)
     * AnnotatedTypeMetadata:注释信息
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) 
        // TODO是否linux系统
        //1、能获取到ioc使用的beanfactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //2、获取类加载器
        ClassLoader classLoader = context.getClassLoader();
        //3、获取当前环境信息
        Environment environment = context.getEnvironment();
        //4、获取到bean定义的注册类
        BeanDefinitionRegistry registry = context.getRegistry();
        
        String property = environment.getProperty("os.name");
        
        //可以判断容器中的bean注册情况,也可以给容器中注册bean
        boolean definition = registry.containsBeanDefinition("person");
        if(property.contains("linux"))
            return true;
        
        
        return false;
    

3、WindowsCondition

package com.atguigu.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

//判断是否windows系统
public class WindowsCondition implements Condition 

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) 
        Environment environment = context.getEnvironment();
        String property = environment.getProperty("os.name");
        if(property.contains("Windows"))
            return true;
        
        return false;
    

4、IOCTest

package com.atguigu.test;

import java.util.Map;

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

import com.atguigu.bean.Blue;
import com.atguigu.bean.Person;
import com.atguigu.config.MainConfig;
import com.atguigu.config.MainConfig2;

public class IOCTest 
    @Test
    public void test03()
        String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        //动态获取环境变量的值;Windows 10
        String property = environment.getProperty("os.name");
        System.out.println(property);
        for (String name : namesForType) 
            System.out.println(name);
        
        
        Map<String, Person> persons = applicationContext.getBeansOfType(Person.class);
        System.out.println(persons);
        
    

运行结果:

技术图片

由于当前系统是win10,所以只有Bill对象存在。

那么如何试验得到Linus呢?

技术图片

通过run configuration的-Dos.name,直接更改jvm参数,然后eviroment中取os.name就为linux了。

技术图片

配置在类上

MainConfig

package com.atguigu.config;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

import com.atguigu.bean.Blue;
import com.atguigu.bean.Color;
import com.atguigu.bean.ColorFactoryBean;
import com.atguigu.bean.Person;
import com.atguigu.bean.Red;
import com.atguigu.condition.LinuxCondition;
import com.atguigu.condition.MyImportBeanDefinitionRegistrar;
import com.atguigu.condition.MyImportSelector;
import com.atguigu.condition.WindowsCondition;
import com.atguigu.test.IOCTest;

//类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效;
@Conditional(WindowsCondition.class)
@Configuration
public class MainConfig2 

    /**
     * @Conditional(Condition) : 按照一定的条件进行判断,满足条件给容器中注册bean
     * 
     * 如果系统是windows,给容器中注册("bill")
     * 如果是linux系统,给容器中注册("linus")
     */
    
    @Bean("bill")
    public Person person01()
        return new Person("Bill Gates",62);
    
    
    @Conditional(LinuxCondition.class)
    @Bean("linus")
    public Person person02()
        return new Person("linus", 48);
    

给容器快速导入一个组件

给容器注册组件的方式

1、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
2、@Bean[导入的第三方包里面的组件]
3、@Import[快速给容器中导入一个组件]

  • a、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
  • b、ImportSelector:返回需要导入的组件的全类名数组;
  • c、ImportBeanDefinitionRegistrar:手动注册bean到容器中

4、使用Spring提供的 FactoryBean(工厂Bean);

  • a、默认获取到的是工厂bean调用getObject创建的对象
  • b、要获取工厂Bean本身,我们需要给id前面加一个 && colorFactoryBean

@Import

@Configuration
//@Import导入组件,id默认是组件的全类名
@Import(Color.class,Red.class)
public class MainConfig2 

ImportSelector-----实现这个接口(将需要导入的组件放入数组中)

1、MyImportSelector

package com.atguigu.condition;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector 

    //返回值,就是到导入到容器中的组件全类名
    //AnnotationMetadata:当前标注@Import注解的类的所有注解信息
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) 
        // TODO Auto-generated method stub
        //importingClassMetadata
        //方法不要返回null值
        return new String[]"com.atguigu.bean.Blue","com.atguigu.bean.Yellow";
    

2、MainConfig

package com.atguigu.config;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

import com.atguigu.bean.Blue;
import com.atguigu.bean.Color;
import com.atguigu.bean.ColorFactoryBean;
import com.atguigu.bean.Person;
import com.atguigu.bean.Red;
import com.atguigu.condition.LinuxCondition;
import com.atguigu.condition.MyImportBeanDefinitionRegistrar;
import com.atguigu.condition.MyImportSelector;
import com.atguigu.condition.WindowsCondition;
import com.atguigu.test.IOCTest;

@Configuration
@Import(MyImportSelector.class)
public class MainConfig2 

ImportBeanDefinitionRegistrar-----实现这个接口(创建BeanDefinition,通过BeanDefinitionRegistry.registerBeanDefinition()导入)

1、MyImportBeanDefinitionRegistrar

package com.atguigu.condition;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import com.atguigu.bean.RainBow;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar 

    /**
     * AnnotationMetadata:当前类的注解信息
     * BeanDefinitionRegistry:BeanDefinition注册类;
     *         把所有需要添加到容器中的bean;调用
     *         BeanDefinitionRegistry.registerBeanDefinition手工注册进来
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) 
        
        boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red");
        boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue");
        if(definition && definition2)
            //指定Bean定义信息;(Bean的类型,Bean。。。)
            RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
            //注册一个Bean,指定bean名
            registry.registerBeanDefinition("rainBow", beanDefinition);
        
    

2、MainConfig2

package com.atguigu.config;

import org.springframework.context.annotation.Configuration;
import com.atguigu.condition.MyImportBeanDefinitionRegistrar;

@Configuration
@Import(MyImportBeanDefinitionRegistrar.class)
//@Import导入组件,id默认是组件的全类名
public class MainConfig2 

FactoryBean-----实现spring提供的这个工厂bean

1、ColorFactoryBean

package com.atguigu.bean;

import org.springframework.beans.factory.FactoryBean;

//创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color> 

    //返回一个Color对象,这个对象会添加到容器中
    @Override
    public Color getObject() throws Exception 
        // TODO Auto-generated method stub
        System.out.println("ColorFactoryBean...getObject...");
        return new Color();
    

    @Override
    public Class<?> getObjectType() 
        // TODO Auto-generated method stub
        return Color.class;
    

    //是单例?
    //true:这个bean是单实例,在容器中保存一份
    //false:多实例,每次获取都会创建一个新的bean;
    @Override
    public boolean isSingleton() 
        // TODO Auto-generated method stub
        return false;
    

2、MainConfig2

package com.atguigu.config;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

import com.atguigu.bean.Blue;
import com.atguigu.bean.Color;
import com.atguigu.bean.ColorFactoryBean;
import com.atguigu.bean.Person;
import com.atguigu.bean.Red;
import com.atguigu.condition.LinuxCondition;
import com.atguigu.condition.MyImportBeanDefinitionRegistrar;
import com.atguigu.condition.MyImportSelector;
import com.atguigu.condition.WindowsCondition;
import com.atguigu.test.IOCTest;

@Configuration
public class MainConfig2 
    /**
     * 给容器中注册组件;
     * 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
     * 2)、@Bean[导入的第三方包里面的组件]
     * 3)、@Import[快速给容器中导入一个组件]
     *         1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
     *         2)、ImportSelector:返回需要导入的组件的全类名数组;
     *         3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
     * 4)、使用Spring提供的 FactoryBean(工厂Bean);
     *         1)、默认获取到的是工厂bean调用getObject创建的对象
     *         2)、要获取工厂Bean本身,我们需要给id前面加一个&
     *             &colorFactoryBean
     */
    @Bean
    public ColorFactoryBean colorFactoryBean()
        return new ColorFactoryBean();
    

注:虽然@Bean的是ColorFactoryBean,但是其实是将此工厂内的bean注册到容器中。如果要获取工厂bean本身,getBean("&..."),在名称前加“&”。

以上是关于Spring注解驱动开发-----组件注册的主要内容,如果未能解决你的问题,请参考以下文章

spring注解驱动开发

Spring注解驱动开发

spring注解驱动开发原理剖析

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

Spring注解驱动开发在@Import注解中使用ImportBeanDefinitionRegistrar向容器中注册bean

Spring 注解驱动开发