Spring注入bean的常用的六种方式

2年前 (2022) 程序员胖胖胖虎阿
266 0 0

一.通过注解注入的一般形式

Bean类

public class TestBean{
}

Configuration类
@Configuration注解去标记了该类,这样标明该类是一个Spring的一个配置类,在加载配置的时候会去加载他。

@Bean的注解,标明这是一个注入Bean的方法,会将下面的返回的Bean注入IOC。

//创建一个class配置文件
@Configuration
public class TestConfiguration{
 //将一个Bean交由Spring进行管理
    @Bean
    public TestBean myBean(){
        return new TestBean();
    }
}

测试类

ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
TestBean testBean = cotext.getBean("testBean",TestBean.class);
System.out.println("testBean = " + testBean);

二.通过构造方法注入Bean

我们在生成一个Bean实例的时候,可以使用Bean的构造方法将Bean实现注入
Bean类

@Component
public class TestBeanConstructor {

 private AnotherBean anotherBeanConstructor;

 @Autowired
 public TeanBeanConstructor(AnotherBean anotherBeanConstructor){
     this.anotherBeanConstructor = anotherBeanConstructor;
 }

 @Override
 public String toString() {
     return "TeanBean{" +
         "anotherBeanConstructor=" + anotherBeanConstructor +
         '}';
 }
}

AnotherBean类

@Component(value="Bean的id,默认为类名小驼峰")
public class AnotherBean {
}

Configuration类

@Configuration
@ComponentScan("com.company.annotationbean")
public class TestConfiguration{
}

注解解释

@AutoWired
自动装配🔧
若是在这里注入的时候指定一个Bean的id就要使用@Qualifier注解。
注释可以在 setter 方法中被用于自动连接 bean,就像 @Autowired 注释,容器,一个属性或者任意命名的可能带有多个参数的方法。
还有不解的地方可以直接百度注解有更详细的解释跟实例

@Component(默认单例模式)
@Component 被称为元注释,它是@Repository、@Service、@Controller、@Configuration的父类,理论上可以使用@Component来注释任何需要Spring自动装配的类。但每个注释都有他们自己的作用,用来区分类的作用,Spring文档上也说明后续版本中可能为@Repository、@Service、@Controller、@Configuration这些注释添加其他功能,所以建议大家还是少使用@Component。
  @Repository注解是任何满足存储库角色或构造型(也称为数据访问对象或DAO)的类的标记。该标记的用途之一是异常的自动翻译,如异常翻译中所述。
  @Service注解一般使用在Service层。
  @Controller注解一般使用在Controller层的类,@RestController继承了@Controller。
  @Configuration注解一般用来配置类,用来项目启动时加载的类。
  
@ComponentScan("")
@ComponentScan注解一般用在Spring项目的核心配置类,或者在Spring Boot项目的启动类里使用。作用就是用来扫描@Component及其子类注释的类,用于Spring容器自动装配。@ComponentScan默认是扫描的路径是同级路径及同级路径的子目录,所以把Spring Boot的启动类放在根目录下,@ComponentScan是可以省略不写的。
主要属性:

  1. value属性、basePackages属性
@AliasFor("basePackages")
String[] value() default {};

@AliasFor("value")
String[] basePackages() default {};

这两个值的作用是一样的,是相互别名的关系。内容是填写要扫描的路径,如果是有一个路径,可以不用写value,有几种写法如下:

@ComponentScan("com.zh.service")

@ComponentScan(value = "com.zh.service")

@ComponentScan(value = {"com.zh.dao", "com.zh.service"})
  1. includeFilters属性、excludeFilters属性
    这两个的作用都是过滤器,excludeFilters的作用是剔除values属性内的个别不需要加载的类,而includeFilters一般是和excludeFilters配合使用,就是被excludeFilters剔除的类里面,还需要其中的几个类,就用includeFilters再加上。

举个例子,假设送了excludeFilters剔除了所有注解是Repository的类,但其中一个Stub开头的类,还要用到,就可以按下面的例子这样写。

ComponentScan.Filter[] includeFilters() default {};

    ComponentScan.Filter[] excludeFilters() default {};

Filter作为过滤器的基本对象

@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Filter {
    FilterType type() default FilterType.ANNOTATION;

    @AliasFor("classes")
    Class<?>[] value() default {};

    @AliasFor("value")
    Class<?>[] classes() default {};

    String[] pattern() default {};
}

FilterType是过滤器的类型,定义方式有几种

public enum FilterType {
    ANNOTATION,
    ASSIGNABLE_TYPE,
    ASPECTJ,
    REGEX,
    CUSTOM;

    private FilterType() {
    }
}

三.通过set方法注入Bean

我们可以在一个属性的set方法中去将Bean实现注入
Bean类

@Component
public class TestBeanSet {

 private AnotherBean anotherBeanSet;

 @Autowired
 public void setAnotherBeanSet(AnotherBean anotherBeanSet) {
     this.anotherBeanSet = anotherBeanSet;
 }

 @Override
 public String toString() {
     return "TestBeanSet{" +
         "anotherBeanSet=" + anotherBeanSet +
         '}';
 }
}

Configuration类

@Configuration
@ComponentScan("com.company.annotationbean")
public class TestConfiguration{
}

Test类

ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
TestBean testBean = cotext.getBean("testBean",TestBean.class);
System.out.println("testBean = " + testBean);

四.通过属性去注入Bean

@Component
public class TestBeanProperty {

 @Autowired
 private AnotherBean anotherBeanProperty;

 @Override
 public String toString() {
     return "TestBeanProperty{" +
         "anotherBeanProperty=" + anotherBeanProperty +
         '}';
 }
}

这里可以通过@AutoWired去自动装配它。

五.通过List注入Bean

TestBeanList类

@Component
public class TestBeanList {

 private List<String> stringList;

 @Autowired
 public void setStringList(List<String> stringList) {
     this.stringList = stringList;
 }

 public List<String> getStringList() {
     return stringList;
 }
}

TestConfiguration类()配置类

@Configuration
@ComponentScan("annoBean.annotationbean")
public class TestConfiguration {

    @Bean
    public List<String> stringList(){
       List<String> stringList = new ArrayList<String>();
       stringList.add("List-1");
       stringList.add("List-2");
       return stringList;
    }
}

这里我们将TestBeanList进行了注入,对List中的元素会逐一注入。

下面我们换一种注入List方式
TestConfiguration类

@Bean
//通过该注解设定Bean注入的优先级,不一定连续数字
@Order(34)
public String string1(){
    return "String-1";
}

@Bean
@Order(14)
public String string2(){
    return "String-2";
}

注入与List中泛型一样的类型,会自动去匹配类型,及时这里没有任何List的感觉,只是String的类型,但他会去通过List的Bean的方式去注入。
注意:
第二种方式的优先级高于第一种,当两个都存在的时候,若要强制去使用第一种方式,则要去指定Bean的id即可。

六.通过Map去注入Bean

@Component
public class TestBeanMap {

 private Map<String,Integer> integerMap;

 public Map<String, Integer> getIntegerMap() {
     return integerMap;
 }

 @Autowired
 public void setIntegerMap(Map<String, Integer> integerMap) {
     this.integerMap = integerMap;
 }
}
/**
*第一种注入map方式
*/
@Bean
public Map<String,Integer> integerMap(){
    Map<String,Integer> integerMap = new HashMap<String, Integer>();
    integerMap.put("map-1",1);
    integerMap.put("map-2",2);
    return integerMap;
}
/**
*第二种注入map方式
*/
@Bean
public Integer integer1(){
    return 1;
}

@Bean
public Integer integer2(){
    return 2;
}

这里跟List一样,第二种优先级大于第一种

版权声明:程序员胖胖胖虎阿 发表于 2022年11月7日 下午12:56。
转载请注明:Spring注入bean的常用的六种方式 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...