Heim > Java > javaLernprogramm > Hauptteil

Detaillierte Erläuterung der Verwendung von Annotationen im Spring-Framework von Java

高洛峰
Freigeben: 2017-01-23 10:35:50
Original
1293 Leute haben es durchsucht

1. Verwenden Sie Spring-Annotationen, um Attribute einzufügen

1.1. Wie haben wir Attribute eingefügt, bevor wir Annotationen verwendet haben?

class UserManagerImpl implements UserManager {
  private UserDao userDao;
  public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
  }
  ...
}
Nach dem Login kopieren

Konfiguration Datei:

<bean id="userManagerImpl" class="com.kedacom.spring.annotation.service.UserManagerImpl">
  <property name="userDao" ref="userDao" />
</bean>
<bean id="userDao" class="com.kedacom.spring.annotation.persistence.UserDaoImpl">
  <property name="sessionFactory" ref="mySessionFactory" />
</bean>
Nach dem Login kopieren

1.2. Einführung der @Autowired-Annotation (nicht empfohlen, es wird empfohlen, @Resource zu verwenden)

Implementierung der Klasse (Annotation von Mitgliedsvariablen)

public class UserManagerImpl implements UserManager {
  @Autowired
  private UserDao userDao;
  ...
}
Nach dem Login kopieren

oder (markieren Sie die Methode)

UserManagerImpl implements UserManager {
  private UserDao userDao;
  @Autowired
  public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
  }
  ...
}
Nach dem Login kopieren

Konfigurationsdatei

<bean id="userManagerImpl" class="com.kedacom.spring.annotation.service.UserManagerImpl" />
<bean id="userDao" class="com.kedacom.spring.annotation.persistence.UserDaoImpl">
  <property name="sessionFactory" ref="mySessionFactory" />
</bean>
Nach dem Login kopieren

@Autowired kann Mitgliedsvariablen, Methoden und Konstruktoren mit Anmerkungen versehen, um die automatische Assemblierung abzuschließen. In den beiden oben genannten unterschiedlichen Implementierungen ist die Position der @Autowired-Annotation unterschiedlich. Sie werden das userDao-Attribut automatisch zusammenstellen, wenn Spring die userManagerImpl-Bean initialisiert. Der Unterschied besteht darin, dass Spring das einzige vom Typ UserDao direkt zusammenstellt. Die Bean wird der Mitgliedsvariablen userDao zugewiesen. In der zweiten Implementierung ruft Spring die Methode setUserDao auf, um die einzige Bean des Typs UserDao dem Attribut userDao zuzuordnen.

1.3. Lassen Sie @Autowired funktionieren

Damit @Autowired funktioniert, müssen Sie den folgenden Code zur Konfigurationsdatei hinzufügen

class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
Nach dem Login kopieren

1.4. Der Qualifier

@Autowired wird basierend auf dem Typ automatisch verkabelt. Wenn im obigen Beispiel mehr als eine Bean vom Typ UserDao im Spring-Kontext vorhanden ist, wird eine BeanCreationException ausgelöst. Wenn im Spring-Kontext keine Bean vom Typ UserDao vorhanden ist, wird ebenfalls eine BeanCreationException ausgelöst. Wir können @Qualifier mit @Autowired verwenden, um diese Probleme zu lösen.
1. Es können mehrere UserDao-Instanzen vorhanden sein

@Autowired
public void setUserDao(@Qualifier("userDao") UserDao userDao) {
  this.userDao = userDao;
}
Nach dem Login kopieren

Auf diese Weise findet Spring die Bean mit der ID userDao für die Assemblierung.

2. UserDao-Instanz existiert möglicherweise nicht

   
@Autowired(required = false)
public void setUserDao(UserDao userDao) {
  this.userDao = userDao;
}
Nach dem Login kopieren

1.5 @Resource (JSR-250-Standardannotation, es wird empfohlen, sie anstelle der proprietären @Autowired-Annotation von Spring zu verwenden)

Spring unterstützt nicht nur seine eigene @Autowired-Annotation, sondern auch mehrere in der JSR-250-Spezifikation definierte Annotationen, nämlich @Resource, @PostConstruct und @PreDestroy.
Die Funktion von @Resource entspricht @Autowired, mit der Ausnahme, dass @Autowired automatisch von byType injiziert wird, während @Resource standardmäßig automatisch von byName injiziert wird. @Resource verfügt über zwei wichtige Attribute, nämlich Name und Typ. Spring löst das Namensattribut der @Resource-Annotation in den Namen der Bean auf, und das Typattribut löst sich in den Typ der Bean auf. Wenn daher das Namensattribut verwendet wird, wird die automatische Injektionsstrategie byName verwendet, und wenn das Typattribut verwendet wird, wird die automatische Injektionsstrategie byType verwendet. Wenn weder das Namens- noch das Typattribut angegeben sind, wird die automatische Injektionsstrategie byName über den Reflexionsmechanismus verwendet.
@Resource-Assembly-Reihenfolge

Wenn Name und Typ gleichzeitig angegeben werden, wird die einzige passende Bean aus dem Spring-Kontext für die Assembly gefunden. Wenn sie nicht gefunden wird, wird eine Ausnahme ausgelöst.

Wenn ein Name angegeben ist, suchen Sie die Bean mit einem passenden Namen (ID) aus dem Kontext für die Assembly. Wenn keine Bean gefunden wird, wird eine Ausnahme ausgelöst.
Wenn weder Name noch Typ vorhanden sind Wenn angegeben, wird die Assemblierung automatisch gemäß byName durchgeführt (siehe 2); wenn keine Übereinstimmung vorliegt, wird für die Übereinstimmung auf einen primitiven Typ (UserDao) zurückgegriffen. Wenn eine Übereinstimmung vorliegt, erfolgt die automatische Assemblierung. @PostConstruct (JSR-250)
Fügen Sie der Methode die Annotation @PostConstruct hinzu. Diese Methode wird vom Spring-Container ausgeführt, nachdem die Bean initialisiert wurde (Hinweis: Die Bean-Initialisierung umfasst das Instanziieren der Bean und das Zusammenstellen der Eigenschaften der Bean (Abhängigkeitsinjektion)).
Ein typisches Anwendungsszenario besteht darin, dass Sie eine in der übergeordneten Klasse definierte Eigenschaft in eine Bean einfügen müssen, die Eigenschaft der übergeordneten Klasse oder die Setter-Methode der Eigenschaft jedoch nicht überschreiben können, z. B.:


public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
  private SessionFactory mySessionFacotry;
  @Resource
  public void setMySessionFacotry(SessionFactory sessionFacotry) {
    this.mySessionFacotry = sessionFacotry;
  }
  @PostConstruct
  public void injectSessionFactory() {
    super.setSessionFactory(mySessionFacotry);
  }
  ...
}
Nach dem Login kopieren
Hier fügen wir über @PostConstruct unsere eigene definierte sessionFactory in eine private sessionFactory-Eigenschaft ein, die in der übergeordneten Klasse von UserDaoImpl definiert ist (die setSessionFactory-Methode der übergeordneten Klasse ist endgültig und kann nicht überschrieben werden), und dann können wir darauf zugreifen diese Eigenschaft durch Aufruf von super.getSessionFactory().

1.7. @PreDestroy (JSR-250)

Fügen Sie die Annotation @PreDestroy zur Methode hinzu, und diese Methode wird vom Spring-Container ausgeführt, nachdem die Bean initialisiert wurde. Da wir derzeit keine Szenarien haben, in denen wir es verwenden müssen, werden wir es hier nicht demonstrieren. Seine Verwendung ist die gleiche wie bei @PostConstruct.


1.8. Verwenden Sie , um die Konfiguration zu vereinfachen.
Spring2.1 fügt einen neuen Kontext-Schema-Namespace hinzu, der für Annotationstreiber, die Einführung von Eigenschaftendateien und das Laden von Funktionen nützlich ist Zeitgenössische Webereien bieten eine praktische Konfiguration. Wir wissen, dass die Annotation selbst nichts bewirkt, sondern lediglich Metadateninformationen bereitstellt. Damit Metadateninformationen wirklich nützlich sind, muss der für die Verarbeitung der Metadaten verantwortliche Prozessor eingesetzt werden.

AutowiredAnnotationBeanPostProcessor und CommonAnnotationBeanPostProcessor sind Prozessoren, die diese Annotationsmetadaten verarbeiten. Es ist jedoch umständlich, diese Beans direkt in der Spring-Konfigurationsdatei zu definieren. Spring bietet uns eine bequeme Möglichkeit, diese BeanPostProcessors zu registrieren: :



将隐式地向Spring容器注册AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、 PersistenceAnnotationBeanPostProcessor以及RequiredAnnotationBeanPostProcessor这4个BeanPostProcessor。

2. 使用Spring注解完成Bean的定义
以上我们介绍了通过@Autowired或@Resource来实现在Bean中自动注入的功能,下面我们将介绍如何注解Bean,从而从XML配置文件中完全移除Bean定义的配置。

2.1. @Component(不推荐使用)、@Repository、@Service、@Controller
只需要在对应的类上加上一个@Component注解,就将该类定义为一个Bean了:

@Component
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
  ...
}
Nach dem Login kopieren

使用@Component注解定义的Bean,默认的名称(id)是小写开头的非限定类名。如这里定义的Bean名称就是userDaoImpl。你也可以指定Bean的名称:
@Component("userDao")
@Component是所有受Spring管理组件的通用形式,Spring还提供了更加细化的注解形式:@Repository、@Service、@Controller,它们分别对应存储层Bean,业务层Bean,和展示层Bean。目前版本(2.5)中,这些注解与@Component的语义是一样的,完全通用,在Spring以后的版本中可能会给它们追加更多的语义。所以,我们推荐使用@Repository、@Service、@Controller来替代@Component。

2.2. 使用让Bean定义注解工作起来

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-2.5.xsd">
  <context:component-scan base-package="com.kedacom.ksoa" />
</beans>
Nach dem Login kopieren

这里,所有通过元素定义Bean的配置内容已经被移除,仅需要添加一行配置就解决所有问题了——Spring XML配置文件得到了极致的简化(当然配置元数据还是需要的,只不过以注释形式存在罢了)。的base-package属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
还允许定义过滤器将基包下的某些类纳入或排除。Spring支持以下4种类型的过滤方式:

过滤器类型 表达式范例 说明
注解 org.example.SomeAnnotation 将所有使用SomeAnnotation注解的类过滤出来
类名指定 org.example.SomeClass 过滤指定的类
正则表达式 com\.kedacom\.spring\.annotation\.web\..* 通过正则表达式过滤一些类
AspectJ表达式 org.example..*Service+ 通过AspectJ表达式过滤一些类

以正则表达式为例,我列举一个应用实例:

<context:component-scan base-package="com.casheen.spring.annotation">
  <context:exclude-filter type="regex" expression="com\.casheen\.spring\.annotation\.web\..*" />
</context:component-scan>
Nach dem Login kopieren

值得注意的是配置项不但启用了对类包进行扫描以实施注释驱动Bean定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor),因此当使用后,就可以将移除了。

2.3. 使用@Scope来定义Bean的作用范围
在使用XML定义Bean时,我们可能还需要通过bean的scope属性来定义一个Bean的作用范围,我们同样可以通过@Scope注解来完成这项工作:

@Scope("session")
@Component()
public class UserSessionBean implements Serializable {
  ...
}
Nach dem Login kopieren

3.在使用annotation之前定义三个bean之间的关系是这样的

package com.baobaotao;
public class Office {
  private String officeNo =”001”;
  
  //省略 get/setter
  
  @Override
  public String toString() {
    return "officeNo:" + officeNo;
  }
}
 
ackage com.baobaotao;
  
public class Car {
  private String brand;
  private double price;
  
  // 省略 get/setter
  
  @Override
  public String toString() {
    return "brand:" + brand + "," + "price:" + price;
  }
}
 
package com.baobaotao;
  
public class Boss {
  private Car car;
  private Office office;
  
  // 省略 get/setter
  
  @Override
  public String toString() {
    return "car:" + car + "\n" + "office:" + office;
  }
}
Nach dem Login kopieren

配置文件如下:

   
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  <bean id="boss" class="com.baobaotao.Boss">
    <property name="car" ref="car"/>
    <property name="office" ref="office" />
  </bean>
  <bean id="office" class="com.baobaotao.Office">
    <property name="officeNo" value="002"/>
  </bean>
  <bean id="car" class="com.baobaotao.Car" scope="singleton">
    <property name="brand" value=" 红旗 CA72"/>
    <property name="price" value="2000"/>
  </bean>
</beans>
Nach dem Login kopieren

测试文件如下:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AnnoIoCTest {
  
  public static void main(String[] args) {
    String[] locations = {"beans.xml"};
    ApplicationContext ctx =
      new ClassPathXmlApplicationContext(locations);
    Boss boss = (Boss) ctx.getBean("boss");
    System.out.println(boss);
  }
}
Nach dem Login kopieren


4.接下来我们可以使用autowired来注解,他可以对成员变量,方法及构造函数进行标准,完成自动装配的工作。

autoware来注解成员变量的用法

package com.baobaotao;
import org.springframework.beans.factory.annotation.Autowired;
  
public class Boss {
  
  @Autowired
  private Car car;
  
  @Autowired
  private Office office;
  
  …
}
Nach dem Login kopieren

相应的配置文件如下:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  
  <!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->
  <bean class="org.springframework.beans.factory.annotation.
    AutowiredAnnotationBeanPostProcessor"/>
  
  <!-- 移除 boss Bean 的属性注入配置的信息 -->
  <bean id="boss" class="com.baobaotao.Boss"/>
  
  <bean id="office" class="com.baobaotao.Office">
    <property name="officeNo" value="001"/>
  </bean>
  <bean id="car" class="com.baobaotao.Car" scope="singleton">
    <property name="brand" value=" 红旗 CA72"/>
    <property name="price" value="2000"/>
  </bean>
</beans>
Nach dem Login kopieren

autoware也可以用在setter方法及构造函数上

package com.baobaotao;
  
public class Boss {
  private Car car;
  private Office office;
  
   @Autowired
  public void setCar(Car car) {
    this.car = car;
  }
  
  @Autowired
  public void setOffice(Office office) {
    this.office = office;
  }
  …
}
 
package com.baobaotao;
  
public class Boss {
  private Car car;
  private Office office;
  
  @Autowired
  public Boss(Car car ,Office office){
    this.car = car;
    this.office = office ;
  }
  
  …
}
Nach dem Login kopieren

当候选bean的数目为0时,我们可以使用@Autowired(required = false)来防止spring找不到bean时报错。

当有多个候选bean的时候,我们可以通过@Qualifier 注释指定注入 Bean 的名称。

@Autowired 和 @Qualifier 结合使用时,自动注入的策略就从 byType 转变成 byName 了。@Autowired 可以对成员变量、方法以及构造函数进行注释,而 @Qualifier 的标注对象是成员变量、方法入参、构造函数入参。正是由于注释对象的不同,所以 Spring 不将 @Autowired 和 @Qualifier 统一成一个注释类。

5.@resorce是按照名字来进行反射,他有两个参数,name和type,使用name即按照byname来映射,使用type即按照bytype来进行映射。

package com.baobaotao;
  
import javax.annotation.Resource;
  
public class Boss {
  // 自动注入类型为 Car 的 Bean
  @Resource
  private Car car;
  
  // 自动注入 bean 名称为 office 的 Bean
  @Resource(name = "office")
  private Office office;
}
@postconstructor和preDestory是用来注解类初始化后和销毁前的方法。
 
 
package com.baobaotao;
  
import javax.annotation.Resource;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
  
public class Boss {
  @Resource
  private Car car;
  
  @Resource(name = "office")
  private Office office;
  
  @PostConstruct
  public void postConstruct1(){
    System.out.println("postConstruct1");
  }
  
  @PreDestroy
  public void preDestroy1(){
    System.out.println("preDestroy1");
  }
  …
}
Nach dem Login kopieren

6.@compent可以直接定义bean,这样xml配置文件中就不需要配置bean了

package com.baobaotao;
  
import org.springframework.stereotype.Component;
  
@Component
public class Car {
  …
}
 
package com.baobaotao;
  
import org.springframework.stereotype.Component;
  
@Component
public class Office {
  private String officeNo = "001";
  …
}
 
package com.baobaotao;
  
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
  
@Component("boss")
public class Boss {
  @Autowired
  private Car car;
  
  @Autowired
  private Office office;
  …
}
Nach dem Login kopieren

@Component 有一个可选的入参,用于指定 Bean 的名称,在 Boss 中,我们就将 Bean 名称定义为“boss”。一般情况下,Bean 都是 singleton 的,需要注入 Bean 的地方仅需要通过 byType 策略就可以自动注入了,所以大可不必指定 Bean 的名称。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-2.5.xsd">
  <context:component-scan base-package="com.baobaotao"/>
</beans>
Nach dem Login kopieren

7.@scope可以用来指定其目标

package com.baobaotao;
import org.springframework.context.annotation.Scope;
…
@Scope("prototype")
@Component("boss")
public class Boss {
Nach dem Login kopieren


Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。虽然目前这 3 个注释和 @Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释。

更多详解Java的Spring框架中的注解的用法相关文章请关注PHP中文网!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!