开发者

Spring三种方法的注解自动注入问题

目录
  • Spring三种方法的注解自动注入
    • 1 @Autowired注解
    • 2 @Resource
    • 3 @Inject
  • Spring 注解版 属性赋值 自动注入
    • 总结

      Spring三种方法的注解自动注入

      1 @Autowired注解

      @Autowired是Spring提供的自动注入的方法,该注解可以放在变量和方法上,在bean+返回值类型的注解中,@Autowired还可以放在参数前;@Autowired默认的注入是根据类型注入,如果相同类型的bean有多个,可以配合@Qualifier使用,则会根据名字自动注入;除了配合@Qualifier使用之外,还可以在相同类型的多个bean中的其中一个加上@Primary注解,那么根据类型注入就会第一注入有@Primary注解的bean。

      示例代码:

      @Repository("stuDao1")
      public class StudentDaoImpl1 implements StudentDao {
      }
      @Primary
      @Repository("stuDhttp://www.devze.comao2")
      public class StudentDaoImpl2 implements StudentDao {
      }
      @Service("stuService")
      public class StudentService {
      	
      	@Autowired	//从IOC容器中找到StudentDao类型的be编程an加入到studentDao中,AutoWired注入不调用set方法
      	@Qualifier("stuDao")
      	private StudentDao studentDao;
       
      	//@Autowired	//也可以把AutoWired注解放到set方法上,并且会调用set方法
      	public void setStudentDao(StudentDao studentDao) {
      		this.studentDao = studentDao;
      	}
      }

      2 @Resource

      @Resource注解是Java规范(jsR250)提供的方法,该注解默认是根据bean的名字自动注入,如果没有找到对应的名字,则会自动根据类型查找并注入,可以使用name和type来指定根据名字还是类型来查找;@Resource注解同样可以使用@Primary。

      示例代码:

      public class StudentService {
       
      //	@Resource(name="stuDao1") //根据名字查找bean
      	@Resource(type=StudentDao.class)    //根据类型查找bean
      	private StudentDao studentDao;
       
      //  @Resource    //放在方法上
      	public void setStujsdentDao(StudentDao studentDao) {
      		this.studentDao = studentDao;
      	}
      }

      3 @Inject

      @Inject注解也是Java规范(JSR330)提供的方法,该注解默认是根据bean的类型自动注入,不过使用此注解需要导入javax-Inject.jar包;使用方法和@Autowired差不多一样,也可以配合@Qualifier和@Primary使用。

      javax-Inject.jar下载地址

      示例代码

      @Service("stuService")
      public class StudentService {
       
      //	@Inject
      //	@Qualifier("stuDao2")
      	private StudentDao studentDao;
       
      	@Inject
      	@Qualifier("stuDao2")
      	public void setStudentDao(StudentDao studentDao) {
      		this.studentDao = studentDao;
      	}
       
      }

      Spring 注解版 属性赋值 自动注入

      spring的属性赋值,给一个bean的属性进行赋值,可以使用@Value注解。

      该注解可以注入基本数值,字符串什么的@Value("zhangsan"),也可以结合SpEL表达式@Value("#{18+1}"),还可以读取配置文件中的属性@Value("${person.nickname}")(pandroiderson.nickname,是外部配置文件的一个属性名)。

      PersojsgRmcvn.java(一个普通的bean)

      package com.sixteen.entity;
      
      import lombok.Data;
      import org.springframework.beans.factory.annotation.Value;
      
      @Data
      public class Person {
      
        /**
        * @Value注解
        * 1. 基本数值都可注入
        * 2. SPEl表达式 #{}
        * 3. ${} 获取配置文件中的值
        */
      
        // 配置文件中的值默认加载进环境变量
        /**可以这样在环境中取出
        * ApplicationContext context = new AnnotationConfigApplicationContext(SpringPropertiesValueConfig.class);
        * Environment environment = context.getEnvironment();
        * String property = environment.getProperty("person.nickname");
        * System.out.println(property);
        */
        @Value("zhangsan")
        private String name;
        @Value("#{18+1}")
        private Integer age;
      
        @Value("${person.nickname}")
        private String nickename;
      }

      SpringPropertiesValueConfig.java(配置类)

      package com.sixteen.config;
      
      import com.sixteen.entity.Person;
      import org.springframework.context.annotation.Bean;
      import org.spri开发者_Python入门ngframework.context.annotation.Configuration;
      import org.springframework.context.annotation.PropertySource;
      
      //使用@PropertySource导入外部配置文件,在bean里用@Value注解(@Value("${person.nickname}"))进行属性赋值
      @PropertySource(value = {"classpath:person.properties"})
      @Configuration
      public class SpringPropertiesValueConfig {
      
        @Bean
        public Person person(){
          return new Person();
        }
      }

      person.properties(外部配置文件)

      person.nickname="xiaosan"

      这样就可以给实体类(bean)的属性进行赋值了,在springboot中读取外部配置文件的值时,还可以使用@ConfigurationProperties,这个注解之后再详细说,也可以百度查询资料,不过一般用于需要赋值的属性过多时可以考虑,因为这一个注解就可以将所有属性赋值,而不像@Value需要在每个属性上加上。

      自动注入(又被叫做DI注入)即在一个组件中如果想用另一个组件就可以注入想用的组件(因为spring接管了所有的bean和组件,所以想要用别的bean或者组件就得从IOC容器中获取)。最典型的例子就是,在service层需要调用dao层方法(或者叫做mapper)这个时候就可以采用自动注入。

      此时使用的配置文件和上面的配置文件不一样

      SpringAutowiredConfig,java

      package com.sixteen.config;
      
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      
      /**
      * @Autowired 自动注入
      *
      * @Autowired
      * private YyyMapper mapper;
      * 1) 默认按照类型去容器中找对应的组件,找到就赋值 context.getBean(SpringService.class);
      * 2) 如果找到多个相同类型的组件,再将属性的名称(mapper)作为组件id去容器查找 context.getBean("mapper")
      * @Qualifier(),传入bean的id,可以指定注入的bean,而不是用属性名
      *
      * 自动装配默认装配好,如果找不到组件,就报错
      * 也可以设置@Autowired(require=false),如果找不到装配的组件就不装配,也不会报错
      *
      * 可以使用@Primary注解,使装配首选为该bean,使用此注解时可再用@Qualifier()
      * XxxService{
      *   YyyMapeer mapper;
      * }
      */
      
      @Configuration
      @ComponentScan(basePackages = {"com.sixteen.service","com.sixteen.mapper"})
      public class SpringAutowiredConfig {
      }

      SpringService.java(service层)

      package com.sixteen.service;
      
      import com.sixteen.mapper.SpringMapper;
      import lombok.Data;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      
      @Service
      public class SpringService {
      
        @Autowired
        private SpringMapper mapper;
      }

      SpringMapper.java

      package com.sixteen.mapper;
      
      import org.springframework.stereotype.Repository;
      
      @Repository
      public class SpringMapper {
      }

      一般情况这样注入是没问题的,但如果你想自动注入的组件/bean有多个在IOC容器时,那么就有可能注入的不是你所想要的,具体规则如下:

      /**
      * @Autowired 自动注入
      *
      * @Autowired
      * private YyyMapper mapper;
      * 1) 默认按照类型去容器中找对应的组件,找到就赋值 context.getBean(SpringService.class);
      * 2) 如果找到多个相同类型的组件,再将属性的名称(mapper)作为组件id去容器查找 context.getBean("mapper")
      * @Qualifier(),传入bean的id,可以指定注入的bean,而不是用属性名
      *
      * 自动装配默认装配好,如果找不到组件,就报错
      * 也可以设置@Autowired(require=false),如果找不到装配的组件就不装配,也不会报错
      *
      * 可以使用@Primary注解,使装配首选为该bean,使用此注解时可再用@Qualifier()
      * XxxService{
      *   YyyMapeer mapper;
      * }
      */

      像service层中属性这样写的话,@Autowired private SpringMapper mapper;,如果IOC容器中有不止一个SpringMapper这种组件,那么就会根据mapper这个临时起的属性名,作为bean的id去IOC容器中查找是否有组件,所以在必要时,一个属性的名称不要随意起变量名。

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

      0

      上一篇:

      下一篇:

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      最新开发

      开发排行榜