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; } ... }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>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; ... }oder (markieren Sie die Methode)
UserManagerImpl implements UserManager { private UserDao userDao; @Autowired public void setUserDao(UserDao userDao) { this.userDao = userDao; } ... }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>@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" />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; }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; }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 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); } ... }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 bfe8fab089282832fed14fcb6f680c1e, 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.
02b5e3170f8825be11991279b556a682将隐式地向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 { ... }
使用@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. 使用5fac6a8af37bdf6785fe01c166cb3779让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>
这里,所有通过60e23eb984d18edbb092da6b8f295aba元素定义Bean的配置内容已经被移除,仅需要添加一行5fac6a8af37bdf6785fe01c166cb3779配置就解决所有问题了——Spring XML配置文件得到了极致的简化(当然配置元数据还是需要的,只不过以注释形式存在罢了)。5fac6a8af37bdf6785fe01c166cb3779的base-package属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
5fac6a8af37bdf6785fe01c166cb3779还允许定义过滤器将基包下的某些类纳入或排除。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>
值得注意的是5fac6a8af37bdf6785fe01c166cb3779配置项不但启用了对类包进行扫描以实施注释驱动Bean定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor),因此当使用5fac6a8af37bdf6785fe01c166cb3779后,就可以将bfe8fab089282832fed14fcb6f680c1e移除了。
2.3. 使用@Scope来定义Bean的作用范围
在使用XML定义Bean时,我们可能还需要通过bean的scope属性来定义一个Bean的作用范围,我们同样可以通过@Scope注解来完成这项工作:
@Scope("session") @Component() public class UserSessionBean implements Serializable { ... }
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; } }
配置文件如下:
<?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>
测试文件如下:
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); } }
4.接下来我们可以使用autowired来注解,他可以对成员变量,方法及构造函数进行标准,完成自动装配的工作。
autoware来注解成员变量的用法
package com.baobaotao; import org.springframework.beans.factory.annotation.Autowired; public class Boss { @Autowired private Car car; @Autowired private Office office; … }
相应的配置文件如下:
<?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>
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 ; } … }
当候选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"); } … }
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; … }
@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>
7.@scope可以用来指定其目标
package com.baobaotao; import org.springframework.context.annotation.Scope; … @Scope("prototype") @Component("boss") public class Boss {
Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。虽然目前这 3 个注释和 @Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释。
更多详解Java的Spring框架中的注解的用法相关文章请关注PHP中文网!