@Autowired、@Resource、和@Service註解詳解

註解以前spring怎麼裝配bean

傳統的Spring作法是使用.xml文件來對bean進行注入或者是配置aop、事務。咱們先看一個不使用註解的Spring示例,在這個示例的基礎上,改爲註解版本的,這樣也能看出使用與不使用註解之間的區別,先定義一個老師:java

public class Teacher{
    private String teacherName = "TW";
    public String toString() {
        return "TeacherName:" + teacherName;
    }
}
複製代碼

再定義一個學生:spring

public class Student{
    private String studentName = "SL";
    public String toString() {
        return "StudentName:" + studentName;
    }
}
複製代碼

而後定義一個學校:markdown

public class School{
    private Teacher teacher;
    private Student student;
    public void setTeacher(Teacher teacher){
        this.teacher = teacher;
    }
    public void setStudent(Student student){
        this.student = student;
    }
    public Teacher getTeacher(){
        return teacher;
    }
    public Student getStudent(){
        return student;
    }
    public String toString(){
        return teacher + "\n" + student;
    }
}
複製代碼

spring的配置文件這麼寫:this

<?xml version="1.0" encoding="UTF-8"?>
<bean id="school" class="com.zxt.bean.School" >
    <property name="teacher" ref="teacher" />
    <property name="student" ref="student" />
</bean>
<bean id="teacher" class="com.zxt.uu.Teacher" />
<bean id="student" class="com.zxt.uu.Student" />
複製代碼

這是最初始的.xml配置,很顯然這麼作有兩個缺點:spa

  1. 若是全部的內容都配置在.xml文件中,會致使.xml文件過大;若是按需求分開.xml文件,又會致使.xml文件過多。總之這會使得配置文件的可讀性與可維護性變得很低。
  2. 開發中,在.java文件和.xml文件之間不斷切換,是一件麻煩的事。同時這種思惟上的不連貫也會下降開發的效率。

爲了解決這兩個問題,Spring引入了註解,經過@註解名的方式,讓註解與Java Bean緊密結合,既大大減小了配置文件的體積,又增長了Java Bean的可讀性與內聚性。code

@Autowired

顧名思義,就是自動裝配。其做用是替代Java代碼裏面的getter/setter與bean屬性中的property。若是私有屬性須要對外提供的話,getter應當予以保留。引入@Autowired註解,先看一下spring配置文件怎麼寫:component

1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-4.2.xsd">
 9     
10     <context:component-scan base-package="com.zxt" />
11     
12     <bean id="school" class="com.zxt.bean.School" />
13     <bean id="teacher" class="com.zxt.uu.Teacher" />
14     <bean id="student" class="com.zxt.uu.Student" />
15     
16 </beans>
複製代碼

注意第10行,爲了實現bean的自動載入,必須配置spring的掃描器。orm

在base-package指明一個包:xml

<context:component-scan base-package=「com.zxt」/>
複製代碼

代表com.zxt包及其子包中,若是某個類的頭上帶有特定的註解@Component@Repository@Service@Controller,就會將這個對象做爲Bean注入進spring容器。對象

看到第12行,原來school裏面應當注入兩個屬性teacher、student,如今不須要注入了。再看下,School.java也很簡練,把getter/setter均可以去掉:

public class School{
    @Autowired
    private Teacher teacher;
    @Autowired
    private Student student;
    public String toString(){
        return teacher + "\n" + student;
    }
}
複製代碼

這裏@Autowired註解的意思就是,當Spring發現@Autowired註解時,將自動在代碼上下文中找到與其匹配(默認是類型匹配)的Bean,並自動注入到相應的地方去。

@Resource

@Resource註解做用與@Autowired很是類似。先看一下@Resource,直接寫School.java了:

public class School{
    @Resource(name = "teacher")
    private Teacher teacher;
    @Resource(type = Student.class)
    private Student student;
    public String toString(){
        return teacher + "\n" + student;
    }
}
複製代碼

這是詳細一些的用法,說一下@Resource的裝配順序:

  1. @Resource後面沒有任何內容,默認經過name屬性去匹配bean,找不到再按type去匹配。
  2. 指定了name或者type則根據指定的類型去匹配bean。
  3. 指定了name和type則根據指定的name和type去匹配bean,任何一個不匹配都會報錯。

@Autowired和@Resource兩個註解的區別:

  1. @Autowired默認按照byType方式進行bean匹配,@Resource默認按照byName方式進行bean匹配
  2. @Autowired是Spring的註解,@Resource是J2EE的註解,根據導入註解的包名就能夠知道。
  3. Spring屬於第三方的,J2EE是Java本身的東西。所以,建議使用@Resource註解,以減小代碼和Spring之間的耦合。

@Service

使用@Service,能夠更加簡化.xml文件配置。

由於spring的配置文件裏面還有12行~14行三個bean,應用spring配置文件裏面一個自動掃描的標籤,能夠把這三個bean也給去掉,加強Java代碼的內聚性並進一步減小配置文件。先看一下配置文件:

1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-4.2.xsd">
 9     
10     <context:component-scan base-package="com.zxt" />
11 </beans>
複製代碼

配置文件看起來特別清爽。School.java,Teacher.java和Student.java分別作以下修改:

@Service 
public class School{ 
    @Autowired 
    private Teacher teacher; 
    @Autowired 
    private Student student; 
    public String toString(){ 
        return teacher + "\n" + student; 
    } 
} 
複製代碼
@Service 
public class Teacher{
    private String teacherName = "TW";
    public String toString() {
        return "TeacherName:" + teacherName;
    }
}
複製代碼
@Service
public class Student{
    private String studentName = "SL";
    public String toString() {
        return "StudentName:" + studentName;
    }
}
複製代碼

這樣,School.java在Spring容器中存在的形式就是"school",便可以經過ApplicationContext的getBean("school")方法來獲得School.java。

@Service註解,其實作了兩件事情:

  1. 聲明School.java是一個bean。這點很重要,由於School.java是一個bean,其餘的類纔可使用@Autowired將School做爲一個成員變量自動注入。
  2. School.java在bean中的id是"school",即類名且首字母小寫。
相關文章
相關標籤/搜索