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();


    }

 

  二,@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 註解 源碼,   

也就是說, 在我們使用@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 沒有實例化的,  也不會出現什麼異常。   

  這也是  @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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章