spring中组件注册的几种方法(使用注解方式)

所使用的spring的版本为:4.3.12.RELEASE

一、包扫描+组件标注注解

这个就是我们常用的几种注解

@Controller,@Service,@Repository,@Component

指定相关的配置类

@Configuration  //告诉spring这是一个配置类
@ComponentScan(
 value = {"com.nanc"},
 excludeFilters =
 {
 @ComponentScan.Filter(type = FilterType.ANNOTATION, classes= {Controller.class,Service.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {MyTest.class})
 }, useDefaultFilters = false)
public class MainConfig {

}

@Component中excludeFilters的简要说明

这个注解会扫描指定的包及其子包,可以是一个字符串的数组

excludeFilters:指定不扫描哪些组件,它的值也是一个@ComponentScan.Filter类型的数组

可选类型有:

FilterType.ANNOTATION 按照注解
FilterType.ASSIGNABLE_TYPE 按照给定的类型
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则

二、使用@Bean导入

package com.nanc.config;

import com.nanc.entity.Person;
import org.springframework.context.annotation.*;

@Configuration
public class MainConfig {

   @Scope("prototype")
   @Lazy
   @Bean
   public Person person(){
      System.out.println("给容器中添加Person....");
      return new Person(1, "haha");
   }
}

@Scope注解说明:

@Scope用来调整Bean的作用域,可选取值[singleton,prototype,request,session]等

singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。以后每次获取就是直接从容器(map.get())中拿。

prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象;

request:同一次请求创建一个实例

session:同一个session创建一个实例

@Lazy

懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;

没有此注解时,单实例bean:默认在容器启动的时候创建对象;

三、使用@Import 快速给容器中导入一个组件

使用此注解有三种方式

1、直接导入实体类

package com.nanc.config;

import com.nanc.entity.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(User.class)
public class MainConfig {
}

2、引入一个实现了ImportSelector的类

package com.nanc.condition;

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

public class MyImportSelector implements ImportSelector {
    
    /**
     * AnnotationMetadata: 当前标注@Import注解的类的所有注释信息
     * @param importingClassMetadata
     * @return  要导入到容器中的组件全类名
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //return new String[0];
        return new String[]{"com.nanc.entity.User1", "com.nanc.entity.User2"};
    }
}


package com.nanc.config;

import com.nanc.condition.MyImportSelector;
import com.nanc.entity.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({User.class,MyImportSelector.class})
public class MainConfig {
}

3、导入一个实现了ImportBeanDefinitionRegistrar接口 的类

package com.nanc.condition;

import com.nanc.entity.RainBow;
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;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {


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


package com.nanc.config;

import com.nanc.condition.MyImportBeanDefinitionRegistrar;
import com.nanc.condition.MyImportSelector;
import com.nanc.entity.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({User.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
}

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

package com.nanc.entity;

import org.springframework.beans.factory.FactoryBean;

/**
 * 创建一个Spring定义的FactoryBean
 */
public class ColorFactoryBean implements FactoryBean {
   /**
    * 返回一个Color对象,这个对象会添加到容器中
    * @return
    * @throws Exception
    */
   @Override
   public Color getObject() throws Exception {
      System.out.println("----------ColorFactoryBean------------------");
      return new Color();
   }

   @Override
   public Class getObjectType() {
      return Color.class;
   }

   /**
    * 控制这个bean是否是单例模式?
    *
    * true: 单例
    * false: 多实例,每次创建都会获取一个新的
    * @return
    */
   @Override
   public boolean isSingleton() {
      return true;
   }
}

把上面的类放入到spring容器中(可以使用@Component注解,也是在配置类中使用@Bean进行注入)

测试类

@Test
public void test(){
   ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);


   //工厂Bean获取的是调用getObject创建的对象
   Object bean2 = applicationContext.getBean("colorFactoryBean");
   Object bean3 = applicationContext.getBean("colorFactoryBean");
   System.out.println("bean的类型:"+bean2.getClass());
   System.out.println(bean2 == bean3);

   //前面加一个& 获取的就是ColorFactoryBean的本身实例
   Object bean4 = applicationContext.getBean("&colorFactoryBean");
   System.out.println(bean4.getClass());
}

你可能感兴趣的:(spring中组件注册的几种方法(使用注解方式))