@Autowired & @Resource 區別 & 解讀@Bean


一樣    

  Autowired & @Resource 都可以用來Bean的注入,可以寫在屬性(字段)上、也可以寫在setter方法上

不一樣

  1.來源不一樣

    @Autowired 由Spring提供

    @Resource 由J2EE提供

  2.注入方式不一樣

    @Autowired 默認ByType(按類型注入),若需按名字,則配合使用@Qualifier,默認依賴對象必須存在,若允許不存在,需指定required=false

    @Resource 默認ByName(按名字注入),若找不到對應的Bean,會繼續按類型去找;但一旦指定了name,那么只會按名字去找Bean

  3.不重要的不一樣

     @Autowired 使用屬性(字段)注入的話,有的編譯器要警告,建議使用構造方法注入;@Resource 則不會,然而,@Resource不能使用構造方法注入

     如果使用屬性(字段)注入的話,則容易出現NullPointerException;如果使用setter方法注入,則屬性不能設置為final

 爭論:

  有人說使用@Resource可以解耦(個人不太認同,為什么呢?)

  首先,使用注解進行對Bean的注入,但是,我們得需要一個機制(一些處理類<解析器>)來對這些使用了@Autowired & @Resource 進行解析,比如:

    AutowiredAnnotationBeanPostProcessor
    CommonAnnotationBeanPostProcessor
    PersistenceAnnotationBeanPostProcessor
    RequiredAnnotationBeanPostProcessor
  然而以上這些解析類都是由Spring提供的,所以說,不太能解耦啊(我是這樣理解的,歡迎指正)
 
引申:
  我們會在applicationContext.xml 中配置 <context:annotation-config/> ----這句話的作用就是: 激活那些已經在spring容器里注冊過的bean,@Autowired 、@Resource注解本身不能做任何事情,我們需要一些工具來處理這些,而這句配置就是來加載這里工具(如上面的四個Processor)
   另外,上述這句配置並不能夠注冊Bean到Spring容器中(也就是說不能去處理@Component、@Service等這樣的注解,那什么能處理這些注解呢?<如何將Bean注冊到Spring容器中,不要跟我說xml配置的那種過時的方式哈^_^>)
 
  由上述就會引出這一個配置項: <context:component-scan base-package="com.xxx"/>
   這個配置的作用:
    a>.就是掃面base-package指定的包路徑下的類,並將使用了@Component、@Service等這樣的注解的類,注冊到Spring容器中去
    b>.同時兼備  <context:annotation-config/>這個配置的功能,激活處理@Autowired 、@Resource的工具類
 
  另外的話:
   在使用applicationContext.xml配置的時候,在SpringBoot項目中,可使用@ImportResource(value={"classpath:applicationContext.xml"})進行加載配置文件
   如果在applicationContext.xml中指定了掃描指定包路徑下的Bean,<context:component-scan base-package="com.xxx"/>
   這個時候並沒什么卵用,SpringBoot項目會默認掃描ApplicationMain啟動類所在的包路徑及子包路徑
   但是,如果同時使用了@ImportResource & @ComponentScan 的話,就只會掃描這applicationContext.xml及@ComponentScan中指定的包路徑下的Bean
 
關於@Bean:
   關於為什么會有@Bean的存在,我的理解,可能Spring為了OO,而有了@Bean,進而取代了xml中bean,從而減少了配置文件
   @Bean 使用在方法上,並且一般是搭配@Configuration一起使用,與@Component一起使用的時候是有區別的
  以下兩段代碼中,代碼1中,Student只會實例化一次(使用了CGLib),但在代碼2中,Student會實例化兩次
至於CGLIB代理的流程,參考:https://my.oschina.net/guangshan/blog/1807721
@Configuration
public class BeanConfig {
    @Bean
    public Student student() {
        return new Student();
    }

    @Bean
    public Course course() {
        return new Course(student());
    }
}
@Component
public class BeanConfig {
    @Bean
    public Student student() {
        return new Student();
    }

    @Bean
    public Course course() {
        return new Course(student());
    }
}
在Spring中注冊Bean
  1. 掃描(@ComponentScan)+ 組件使用注解類(@Controller、@Service、@Repository、@Configuration、@Component);
  2. 用@Bean注解;
  3. 用@Import注解注解;
    • @Import快速注冊;For Example:@Import(value = {BeanConfig.class, UserVO.class}),UserVO可以使用@Component,也可以不使用
    • 實現ImportSelector接口
    • 實現ImportBeanDefinitionRegistrar接口
  4. 用FactoryBean接口;
提及到Bean,就不得不說說 @Scope了--作用域

  基本作用域(singleton、prototype)Web 作用域(reqeust、session、globalsession)自定義作用域。Spring默認使用singleton作用域

  • singleton:單例模式,在整個Spring IoC容器中,使用singleton定義的Bean將只有一個實例

  • prototype:原型模式,每次通過容器的getBean方法獲取prototype定義的Bean時,都將產生一個新的Bean實例

  • request:對於每次HTTP請求,使用request定義的Bean都將產生一個新實例,即每次HTTP請求將會產生不同的Bean實例。只有在Web應用中使用Spring時,該作用域才有效

  • session:對於每次HTTP Session,使用session定義的Bean都將產生一個新實例。同樣只有在Web應用中使用Spring時,該作用域才有效

  • globalsession:每個全局的HTTP Session,使用session定義的Bean都將產生一個新實例。典型情況下,僅在使用portlet context的時候有效。同樣只有在Web應用中使用Spring時,該作用域才有效

 
 https://www.cnblogs.com/leiOOlei/p/3713989.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM