Spring源码深度解析,Spring源码自动装配以及组件,@Vuale示例,@Autowired与@Recource 区别等(六)(附代码示例:)

 

Spring源码深度解析,Spring源码以及组件(六)(附代码示例:Cap9)

目录

Spring源码深度解析,Spring源码以及组件(六)(附代码示例:Cap9)

  一,@Value,即一般都是给 类的 属性  赋值

  二,@Autowired ,即自动装配, spring 利用依赖注入(Di) 完成对IOC容器中的各个组件的依赖关系赋值,并且对 bean 的 加载优先级做处理,

        2.1,@Qualifier, 指定装配组件id 进行加载

        2.2,@Primary,优先加载指定Bean

 三,@Resource(JSR250), 即自动装配

       3.1, @Resource 和  @Autowired 一样都可以装配bean。 缺点:不能支持 @Primary功能,@Autowired(requied = false ) 的功能 。

 四,@Inject(JSR330),   即自动装配,

       4.1,@inject 与 @Autowired 一样可以装配 Bean ,并支持 @Primary功能,可用于非Spring 框架。  缺点: 不能支持  @Autowired(requied = false ) 的功能, 需要引入第三方包 javax.inject

五,项目Demo地址


 

  一,@Value,即一般都是给 类的 属性  赋值

       1.1,示例代码:通过给 User 类  赋值, Cap9 项目源码

                 sex 这个属性, 是通过 properties 文件注入的。   @PropertySource  会把文件去交给 Spring 去扫描,去注入到容器,会加载到 Spring 里面有个类, 环境变量中。

ConfigurableEnvironment environment = applicationContext.getEnvironment();

  通过从环境变量中直接取到  user.sex  的值

environment.getProperty("user.sex")
@PropertySource(value = {"classpath:/test.properties"})
@Configuration
public class Cap9MainConfig {

    @Bean
    public User user(){
        return  new User();
    }

}

properties 文件:

user.sex = 22

 自定义 User 类:  通过  注解  @Value  赋值 初始化 属性。

public class User {

    @Value("张三")
    private String name;

    @Value("30")
    private int age;

    @Value("${user.sex}")
    private String sex;

    public User() {
    }

    public User(String name, int age,String sex) {
        super();
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age + '\'' +
                ", sex=" + sex +
                '}';
    }
}

 测试:

 @Test
    public void test(){
        //将配置类添加到容器中
        AnnotationConfigApplicationContext applicationContext =  new AnnotationConfigApplicationContext(Cap9MainConfig.class);

        User user = (User) applicationContext.getBean("user");

        System.out.println(user);

        //properties 会加载到环境变量中,那么可以从环境变量里直接取 user.sex 的值
        ConfigurableEnvironment environment = applicationContext.getEnvironment();

        System.out.println("environment=====>" + environment.getProperty("user.sex"));

        //关闭容器
        applicationContext.close();


    }

 Spring源码深度解析,Spring源码自动装配以及组件,@Vuale示例,@Autowired与@Recource 区别等(六)(附代码示例:)_第1张图片

  二,@Autowired ,即自动装配, spring 利用依赖注入(Di) 完成对IOC容器中的各个组件的依赖关系赋值,并且对 bean 的 加载优先级做处理。

        2.1,@ Autowired 代码示例: Cap9 项目源码

     声明一个 UserDao

public class UserDao {

    @Value("1")
    private String flag;

    public UserDao() {
    }

    public String getFlag() {

        return flag;
    }

    public void setFlag(String flag) {
        this.flag = flag;
    }

    @Override
    public String toString() {
        return "UserDao{" +
                "flag='" + flag + '\'' +
                '}';
    }
}

 声明一个 业务类。。   使用    注解  @Auto wired   装配到容器中,这里有一个地方,需要注意一下   required 这个属性

下面是 @Autowired 注解 源码,   

Spring源码深度解析,Spring源码自动装配以及组件,@Vuale示例,@Autowired与@Recource 区别等(六)(附代码示例:)_第2张图片

也就是说, 在我们使用@Autowired 注解装配 bean 的时候, @Autowired 源码   required  属性默认为 ture,   也就是说 Spring 容器中必须存在 @Autowired 注解 准备 装配的 Bean,    当然  required 属性  也可以设置为 false ,就是忽略。

 注①: 如果你没有注册 Bean , 而去 使用   类似@Autowired 注解 去装配,会出现下面的异常:

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'userDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.enjoy.Cap9.Dao.UserDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'userDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.enjoy.Cap9.Dao.UserDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

注②:如果你忘记注册,  而 使用   @Autowired (required  =false)   装配的时候忽略没有注册到容器的bean, 打印出来的 Bean 实例 会是 null 没有实例化的,  也不会出现什么异常。   

Spring源码深度解析,Spring源码自动装配以及组件,@Vuale示例,@Autowired与@Recource 区别等(六)(附代码示例:)_第3张图片

  这也是  @Autowired 与 @ Recource  注解   区别 之一。   @Recource  是容器必须有注册了Bean, 没有属性 设置。没有就抛异常

 

 

@Service
public class UserService {

    @Autowired(required = false)
    private UserDao userDao;

    /**
     * 测试是否已经自动装配
     */
    public void println() {
        System.out.println(userDao);
    }
}

以下是配置类:

@ComponentScan({"com.enjoy.Cap9.*"}) //扫描Cap9,下面所有的包
public class Cap9Main2Config {

    @Bean
    public UserDao userDao(){
        return  new UserDao();
    }
}

 

 

        2.2,@Qualifier, 指定装配组件id 进行加载

        2.3,@Primary,优先加载指定Bean

 三,@Resource(JSR250), 也是自动装配,但是 在功能上并没有 Autowired 支持的那么好。

       3.1, @Resource 和  @Autowired 一样都可以装配bean。 缺点:不能支持 @Primary功能,@Autowired(requied = false ) 的功能 。

                 

 四,@Inject(JSR330),   即自动装配,不是 Spring 框架的依赖。

       4.1,@inject@Autowired 一样可以装配 Bean ,并支持 @Primary功能,可用于非Spring 框架。  缺点: 不能支持  @Autowired(requied = false ) 的功能, 需要引入第三方包 javax.inject

五,项目Demo地址

Spring源码深度解析,(附代码示例 码云地址: https://gitee.com/Crazycw/SpringCode.git)

参考资料:  https://docs.spring.io/spring/docs/4.3.18.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/

请看下篇: Spring源码深度解析,Spring核心技术 Aop,详解 Aop(七)(附代码示例:)

https://blog.csdn.net/Crazy_Cw/article/details/93771602

你可能感兴趣的:(Spring)