Spring 之 注解详解

Spring 之 注解详解
Spring 之 注解详解

Spring 之注解详解

概述

注释配置相对于XML 配置具有很多的优势:

它可以充分利用Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。如使用JPA 注释配置ORM 映射时,我们就不需要指定PO 的属性名、类型等信息,如果关系表字段和PO 属性名、类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过Java 反射机制获取。

注释和Java 代码位于一个文件中,而XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和Java 代码放在一起,有助于增强程序的内聚性。而采用独立的XML 配置文件,程序员在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低开发效率。

因此在很多情况下,注释配置比XML 配置更受欢迎,注释配置有进一步流行的趋势。Spring 2.5 的一大增强就是引入了很多注释类,现在您已经可以使用注释配置完成大部分XML 配置的功能。在这篇文章里,我们将向您讲述使用注释进行Bean 定义和依赖注入的内容。

原来我们是怎么做的

在使用注释配置之前,先来回顾一下传统上是如何配置Bean 并完成Bean 之间依赖关系的建立。下面是3 个类,它们分别是Office、Car 和Boss,这3 个类需要在Spring 容器中配置为Bean:

Office 仅有一个属性:

清单1. Office.java

package com.baobaotao;

public class Office {

private String officeNo =”001”;

//省略get/setter

@Override

public String toString() {

return "officeNo:" + officeNo;

}

}

Car 拥有两个属性:

清单2. Car.java

package com.baobaotao;

public class Car {

private String brand;

private double price;

// 省略get/setter

@Override

public String toString() {

return "brand:" + brand + "," + "price:" + price;

}

}

Boss 拥有Office 和Car 类型的两个属性:

清单3. Boss.java

package com.baobaotao;

public class Boss {

private Car car;

private Office office;

// 省略get/setter

@Override

public String toString() {

return "car:" + car + "\n" + "office:" + office;

}

}

我们在Spring 容器中将Office 和Car 声明为Bean,并注入到Boss Bean 中:下面是使用传统XML 完成这个工作的配置文件beans.xml:

清单4. beans.xml 将以上三个类配置成Bean

xmlns:xsi="https://www.360docs.net/doc/f717254303.html,/2001/XMLSchema-instance"

xsi:schemaLocation="https://www.360docs.net/doc/f717254303.html,/schema/beans https://www.360docs.net/doc/f717254303.html,/schema/beans/spring-beans-2.5.xsd">

当我们运行以下代码时,控制台将正确打出boss 的信息:

清单5. 测试类:AnnoIoCTest.java

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

}

}

这说明Spring 容器已经正确完成了Bean 创建和装配的工作。

使用@Autowired 注释

Spring 2.5 引入了@Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。来看一下使用@Autowired 进行成员变量自动注入的代码:

清单6. 使用@Autowired 注释的Boss.java

package com.baobaotao;

import org.springframework.beans.factory.annotation.Autowired;

public class Boss {

@Autowired

private Car car;

@Autowired

private Office office;

}

Spring 通过一个BeanPostProcessor 对@Autowired 进行解析,所以要让@Autowired 起作用必须事先在Spring 容器中声明AutowiredAnnotationBeanPostProcessor Bean。

清单7. 让@Autowired 注释工作起来

xmlns:xsi="https://www.360docs.net/doc/f717254303.html,/2001/XMLSchema-instance"

xsi:schemaLocation="https://www.360docs.net/doc/f717254303.html,/schema/beans

https://www.360docs.net/doc/f717254303.html,/schema/beans/spring-beans-2.5.xsd">

这样,当Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描Spring 容器中所有Bean,当发现Bean 中拥有@Autowired 注释时就找到和其匹配(默认按类型匹配)的Bean,并注入到对应的地方中去。

按照上面的配置,Spring 将直接采用Java 反射机制对Boss 中的car 和office 这两个私有成员变量进行自动注入。所以对成员变量使用@Autowired 后,您大可将它们的setter 方法(setCar() 和setOffice())从Boss 中删除。

当然,您也可以通过@Autowired 对方法或构造函数进行标注,来看下面的代码:

清单8. 将@Autowired 注释标注在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;

}

}

这时,@Autowired 将查找被标注的方法的入参类型的Bean,并调用方法自动注入这些Bean。而下面的使用方法则对构造函数进行标注:

清单9. 将@Autowired 注释标注在构造函数上

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 ;

}

}

由于Boss() 构造函数有两个入参,分别是car 和office,@Autowired 将分别寻找和它们类型匹配的Bean,将它们作为Boss(Car car ,Office office) 的入参来创建Boss Bean。

当候选Bean 数目不为1 时的应对方法

在默认情况下使用@Autowired 注释进行自动注入时,Spring 容器中匹配的候选Bean 数目必须有且仅有一个。当找不到一个匹配的Bean 时,Spring 容器将抛出BeanCreationException 异常,并指出必须至少拥有一个匹配的Bean。我们可以来做一个实验:

清单10. 候选Bean 数目为0 时

xmlns:xsi="https://www.360docs.net/doc/f717254303.html,/2001/XMLSchema-instance"

xsi:schemaLocation=https://www.360docs.net/doc/f717254303.html,/schema/beans

https://www.360docs.net/doc/f717254303.html,/schema/beans/spring-beans-2.5.xsd ">

由于office Bean 被注释掉了,所以Spring 容器中将没有类型为Office 的Bean 了,而Boss 的office属性标注了@Autowired,当启动Spring 容器时,异常就产生了。

当不能确定Spring 容器中一定拥有某个类的Bean 时,可以在需要自动注入该类Bean 的地方可以使用@Autowired(required = false),这等于告诉Spring:在找不到匹配Bean 时也不报错。来看一下具体的例子:

清单11. 使用@Autowired(required = false)

package com.baobaotao;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Required;

public class Boss {

private Car car;

private Office office;

@Autowired

public void setCar(Car car) {

this.car = car;

}

@Autowired(required = false)

public void setOffice(Office office) {

this.office = office;

}

}

当然,一般情况下,使用@Autowired 的地方都是需要注入Bean 的,使用了自动注入而又允许不注入的情况一般仅会在开发期或测试期碰到(如为了快速启动Spring 容器,仅引入一些模块的Spring 配置文件),所以@Autowired(required = false) 会很少用到。

和找不到一个类型匹配Bean 相反的一个错误是:如果Spring 容器中拥有多个候选Bean,Spring 容器在启动时也会抛出BeanCreationException 异常。来看下面的例子:

清单12. 在beans.xml 中配置两个Office 类型的Bean

我们在Spring 容器中配置了两个类型为Office 类型的Bean,当对Boss 的office 成员变量进行自动注入时,Spring 容器将无法确定到底要用哪一个Bean,因此异常发生了。

Spring 允许我们通过@Qualifier 注释指定注入Bean 的名称,这样歧义就消除了,可以通过下面的方法解决异常:

清单13. 使用@Qualifier 注释指定注入Bean 的名称

@Autowired

public void setOffice(@Qualifier("office")Office office) {

this.office = office;

}

@Qualifier("office") 中的office 是Bean 的名称,所以@Autowired 和@Qualifier 结合使用时,自动注入的策略就从byType 转变成byName 了。@Autowired 可以对成员变量、方法

以及构造函数进行注释,而@Qualifier 的标注对象是成员变量、方法入参、构造函数入参。正是由于注释对象的不同,所以Spring 不将@Autowired 和@Qualifier 统一成一个注释类。下面是对成员变量和构造函数入参进行注释的代码:

对成员变量进行注释:

清单14. 对成员变量使用@Qualifier 注释

public class Boss {

@Autowired

private Car car;

@Autowired

@Qualifier("office")

private Office office;

}

对构造函数入参进行注释:

清单15. 对构造函数变量使用@Qualifier 注释

public class Boss {

private Car car;

private Office office;

@Autowired

public Boss(Car car , @Qualifier("office")Office office){

this.car = car;

this.office = office ;

}

}

@Qualifier 只能和@Autowired 结合使用,是对@Autowired 有益的补充。一般来讲,@Qualifier 对方法签名中入参进行注释会降低代码的可读性,而对成员变量注释则相对好一些。

使用JSR-250 的注释

Spring 不但支持自己定义的@Autowired 的注释,还支持几个由JSR-250 规范定义的注释,它们分别是@Resource、@PostConstruct 以及@PreDestroy。

@Resource

@Resource 的作用相当于@Autowired,只不过@Autowired 按byType 自动注入,面@Resource 默认按byName 自动注入罢了。@Resource 有两个属性是比较重要的,分别是name 和type,Spring 将@Resource注释的name 属性解析为Bean 的名字,而type 属性则解析为Bean 的类型。所以如果使用name 属性,则使用byName 的自动注入策略,而使用type 属性时则使用byType 自动注入策略。如果既不指定name 也不指定type 属性,这时将通过反射机制使用byName 自动注入策略。

Resource 注释类位于Spring 发布包的lib/j2ee/common-annotations.jar 类包中,因此在使用之前必须将其加入到项目的类库中。来看一个使用@Resource 的例子:

清单16. 使用@Resource 注释的Boss.java

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;

}

一般情况下,我们无需使用类似于@Resource(type=Car.class) 的注释方式,因为Bean 的类型信息可以通过Java 反射从代码中获取。

要让JSR-250 的注释生效,除了在Bean 类中标注这些注释外,还需要在Spring 容器中注册一个负责处理这些注释的BeanPostProcessor:

class="https://www.360docs.net/doc/f717254303.html,monAnnotationBeanPostProcessor"/>

CommonAnnotationBeanPostProcessor 实现了BeanPostProcessor 接口,它负责扫描使用了JSR-250 注释的Bean,并对它们进行相应的操作。

@PostConstruct 和@PreDestroy

Spring 容器中的Bean 是有生命周期的,Spring 允许在Bean 在初始化完成后以及Bean 销毁前执行特定的操作,您既可以通过实现InitializingBean/DisposableBean 接口来定制初始化之后/ 销毁之前的操作方法,也可以通过 元素的init-method/destroy-method 属性指定初始化之后/ 销毁之前调用的操作方法。关于Spring 的生命周期,笔者在《精通Spring 2.x—企业应用开发精解》第3 章进行了详细的描述,有兴趣的读者可以查阅。

JSR-250 为初始化之后/销毁之前方法的指定定义了两个注释类,分别是@PostConstruct 和@PreDestroy,这两个注释只能应用于方法上。标注了@PostConstruct 注释的方法将在类实例化后调用,而标注了@PreDestroy 的方法将在类销毁之前调用。

清单17. 使用@PostConstruct 和@PreDestroy 注释的Boss.java

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

}

}

您只需要在方法前标注@PostConstruct 或@PreDestroy,这些方法就会在Bean 初始化后或销毁之前被Spring 容器执行了。

我们知道,不管是通过实现InitializingBean/DisposableBean 接口,还是通过 元素的init-method/destroy-method 属性进行配置,都只能为Bean 指定一个初始化/ 销毁的方法。但是使用@PostConstruct 和@PreDestroy 注释却可以指定多个初始化/ 销毁方法,那些被标注@PostConstruct 或@PreDestroy 注释的方法都会在初始化/ 销毁时被执行。

通过以下的测试代码,您将可以看到Bean 的初始化/ 销毁方法是如何被执行的:

清单18. 测试类代码

package com.baobaotao;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AnnoIoCTest {

public static void main(String[] args) {

String[] locations = {"beans.xml"};

ClassPathXmlApplicationContext ctx =

new ClassPathXmlApplicationContext(locations);

Boss boss = (Boss) ctx.getBean("boss");

System.out.println(boss);

ctx.destroy();// 关闭Spring 容器,以触发Bean 销毁方法的执行}

}

这时,您将看到标注了@PostConstruct 的postConstruct1() 方法将在Spring 容器启动时,创建Boss Bean 的时候被触发执行,而标注了@PreDestroy 注释的preDestroy1() 方法将在Spring 容器关闭前销毁BossBean 的时候被触发执行。

使用 简化配置

Spring 2.1 添加了一个新的context 的Schema 命名空间,该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置。我们知道注释本身是不会做任何事情的,它仅提供元数据信息。要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作起来。

而我们前面所介绍的AutowiredAnnotationBeanPostProcessor 和CommonAnnotationBeanPostProcessor 就是处理这些注释元数据的处理器。但是直接在Spring 配置文件中定义这些Bean 显得比较笨拙。Spring 为我们提供了一种方便的注册这些BeanPostProcessor 的方式,这就是。请看下面的配置:

清单19. 调整beans.xml 配置文件

xmlns:xsi="https://www.360docs.net/doc/f717254303.html,/2001/XMLSchema-instance"

xmlns:context="https://www.360docs.net/doc/f717254303.html,/schema/context"

xsi:schemaLocation="https://www.360docs.net/doc/f717254303.html,/schema/beans

https://www.360docs.net/doc/f717254303.html,/schema/beans/spring-beans-2.5.xsd

https://www.360docs.net/doc/f717254303.html,/schema/context

https://www.360docs.net/doc/f717254303.html,/schema/context/spring-context-2.5.xsd">

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

在配置文件中使用context 命名空间之前,必须在 元素中声明context 命名空间。使用@Component

虽然我们可以通过@Autowired 或@Resource 在Bean 类中使用自动注入功能,但是Bean 还是在XML 文件中通过 进行定义——也就是说,在XML 配置文件中定义Bean,通过@Autowired 或@Resource 为Bean 的成员变量、方法入参或构造函数入参提供自动注入的功能。能否也通过注释定义Bean,从XML 配置文件中完全移除Bean 定

义的配置呢?答案是肯定的,我们通过Spring 2.5 提供的@Component 注释就可以达到这个目标了。

为什么@Repository 只能标注在DAO 类上呢?这是因为该注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为Spring 的数据访问异常类型。Spring 本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。

Spring 2.5 在@Repository 的基础上增加了功能类似的额外三个注解:@Component、@Service、@Constroller,它们分别用于软件系统的不同层次:

@Component 是一个泛化的概念,仅仅表示一个组件(Bean) ,可以作用在任何层次。

@Service 通常作用在业务层,但是目前该功能与@Component 相同。

@Constroller 通常作用在控制层,但是目前该功能与@Component 相同。

通过在类上使用@Repository、@Component、@Service 和@Constroller 注解,Spring 会自动创建相应的BeanDefinition 对象,并注册到ApplicationContext 中。这些类就成了Spring 受管组件。这三个注解除了作用于不同软件层次的类,其使用方式与@Repository 是完全相同的。

下面,我们完全使用注释定义Bean 并完成Bean 之间装配:

清单20. 使用@Component 注释的Car.java

package com.baobaotao;

import https://www.360docs.net/doc/f717254303.html,ponent;

@Component

public class Car {

}

仅需要在类定义处,使用@Component 注释就可以将一个类定义了Spring 容器中的Bean。下面的代码将Office 定义为一个Bean:

清单21. 使用@Component 注释的Office.java

package com.baobaotao;

import https://www.360docs.net/doc/f717254303.html,ponent;

@Component

public class Office {

private String officeNo = "001";

}

这样,我们就可以在Boss 类中通过@Autowired 注入前面定义的Car 和Office Bean 了。清单22. 使用@Component 注释的Boss.java

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 https://www.360docs.net/doc/f717254303.html,ponent;

@Component("boss")

public class Boss {

@Autowired

private Car car;

@Autowired

private Office office;

}

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

在使用@Component 注释后,Spring 容器必须启用类扫描机制以启用注释驱动Bean 定义和注释驱动Bean 自动注入的策略。Spring 2.5 对context 命名空间进行了扩展,提供了这一功能,请看下面的配置:

清单23. 简化版的beans.xml

xmlns:xsi="https://www.360docs.net/doc/f717254303.html,/2001/XMLSchema-instance"

xmlns:context="https://www.360docs.net/doc/f717254303.html,/schema/context"

xsi:schemaLocation="https://www.360docs.net/doc/f717254303.html,/schema/beans

https://www.360docs.net/doc/f717254303.html,/schema/beans/spring-beans-2.5.xsd

https://www.360docs.net/doc/f717254303.html,/schema/context

https://www.360docs.net/doc/f717254303.html,/schema/context/spring-context-2.5.xsd">

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

还允许定义过滤器将基包下的某些类纳入或排除。Spring 支持以下4 种类型的过滤方式,通过下表说明:

表1. 扫描过滤方式

过滤器类型说明

注释假如com.baobaotao.SomeAnnotation 是一个注释类,我们可以将使用该注释的类过滤出来。

类名指定通过全限定类名进行过滤,如您可以指定将com.baobaotao.Boss 纳入扫描,而将com.baobaotao.Car 排除在外。

正则表达式通过正则表达式定义过滤的类,如下所示:com\.baobaotao\.Default.* AspectJ 表达式通过AspectJ 表达式定义过滤的类,如下所示:com. baobaotao..*Service+

下面是一个简单的例子:

expression="com\.baobaotao\.service\..*"/>

expression="com.baobaotao.util..*"/>

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

默认情况下通过@Component 定义的Bean 都是singleton 的,如果需要使用其它作用范围的Bean,可以通过@Scope 注释来达到目标,如以下代码所示:

@scopee

清单24. 通过@Scope 指定Bean 的作用范围

package com.baobaotao;

import org.springframework.context.annotation.Scope;

@Scope("prototype")

@Component("boss")

public class Boss {

}

这样,当从Spring 容器中获取boss Bean 时,每次返回的都是新的实例了。

采用具有特殊语义的注释

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

注释配置和XML 配置的适用场合

是否有了这些IOC 注释,我们就可以完全摒除原来XML 配置的方式呢?答案是否定的。有以下几点原因:

注释配置不一定在先天上优于XML 配置。如果Bean 的依赖关系是固定的,(如Service 使用了哪几个DAO 类),这种配置信息不会在部署时发生调整,那么注释配置优于XML 配置;反之如果这种依赖关系会在部署时发生调整,XML 配置显然又优于注释配置,因为注释是对Java 源代码的调整,您需要重新改写源代码并重新编译才可以实施调整。

如果Bean 不是自己编写的类(如JdbcTemplate、SessionFactoryBean 等),注释配置将无法实施,此时XML 配置是唯一可用的方式。

注释配置往往是类级别的,而XML 配置则可以表现得更加灵活。比如相比于@Transaction 事务注释,使用aop/tx 命名空间的事务配置更加灵活和简单。

所以在实现应用中,我们往往需要同时使用注释配置和XML 配置,对于类级别且不会发生变动的配置可以优先考虑注释配置;而对于那些第三方类以及容易发生调整的配置则应优先考虑使用XML 配置。Spring 会在具体实施Bean 创建和Bean 注入之前将这两种配置方式的元信息融合在一起。

springMVC详解以及注解说明

springMVC详解以及注解说明 基于注释(Annotation)的配置有越来越流行的趋势,Spring 2.5 顺应这种趋势,提供了完全基于注释配置Bean、装配Bean 的功能,您可以使用基于注释的Spring IoC 替换原来基于XML 的配置。本文通过实例详细讲述了Spring 2.5 基于注释IoC 功能的使用。 概述 注释配置相对于XML 配置具有很多的优势: ? 它可以充分利用Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。如使用JPA 注释配置ORM 映射时,我们就不需要指定PO 的属性名、类型等信息,如果关系表字段和PO 属性名、类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过Java 反射机制获取。 ? 注释和Java 代码位于一个文件中,而XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和Java 代码放在一起,有助于增强程序的内聚性。而采用独立的XML 配置文件,程序员在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低开发效率。 因此在很多情况下,注释配置比XML 配置更受欢迎,注释配置有进一步流行的趋势。Spring 2.5 的一大增强就是引入了很多注释类,现在您已经可以使用注释配置完成大部分XML 配置的功能。在这篇文章里,我们将向您讲述使用注释进行Bean 定义和依赖注入的内容。 Spring2.5的注释 Spring 2.5 提供了AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 和RequiredAnnotationBeanPostProcessor这四个主要的关于Annotation 的BeanPostProcessor。 我们可以使用 来方便地、一次性的声明者四个BeanPostProcessor。 1.Autowired... 提供对Spring 特有的Autowired 和Qualifier 注释。

spring的@Transactional注解详细用法

spring的@Transactional注解详细用法 各位读友大家好!你有你的木棉,我有我的文章,为了你的木棉,应读我的文章!若为比翼双飞鸟,定是人间有情人!若读此篇优秀文,必成天上比翼鸟! spring的@Transactional注解详细用法Spring Framework对事务管理提供了一致的抽象,其特点如下:为不同的事务API 提供一致的编程模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA(Java Persistence API和JDO(Java Data Objects)支持声明式事务管理,特别是基于注解的声明式事务管理,简单易用提供比其他事务API如JTA更简单的编程式事务管理API与spring数据访问抽象的完美集成事务管理方式spring支持编程式事务管理和声明式事务管理两种方式。编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。显然声明式事务管理要优于编程式事务管理,这正是spring

Spring注解详解

Spring注解详解 目录 一、注解说明 (2) 1.使用简化配置 (2) 2.使用Bean定义注解 (2) 3.Spring支持以下4种类型的过滤方式: (2) 二、注解介绍 (2) 1.@Controller (3) 2.@Service (3) 3.@Autowired (4) 4.@RequestMapping (4) 5.@RequestParam (5) 6.@ModelAttribute (6) 7.@Cacheable和@CacheFlush (7) 8.@Resource (7) 9.@PostConstruct和@PreDestroy (8) 10.@Repository (8) 11.@Component(不推荐使用) (8) 12.@Scope (8) 13.@SessionAttributes (9) 14.@InitBinder (9) 15.@Required (9) 16.@Qualifier (10)

一、注解说明 1.使用简化配置 将隐式地向Spring容器注册以下4个BeanPostProcessor: AutowiredAnnotationBeanPostProcessor CommonAnnotationBeanPostProcessor PersistenceAnnotationBeanPostProcessor RequiredAnnotationBeanPostProcessor 2.使用Bean定义注解 如果要使注解工作,则必须配置component-scan,实际上不需要再配置annotation-config。base-package属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。还允许定义过滤器将基包下的某些类纳入或排除。 3.Spring支持以下4种类型的过滤方式: 1)注解org.example.SomeAnnotation将所有使用SomeAnnotation注解的类过滤出来 2)类名指定org.example.SomeClass过滤指定的类 3)正则表达式com.kedacom.spring.annotation.web..*通过正则表达式过滤一些类 4)AspectJ表达式org.example..*Service+通过AspectJ表达式过滤一些类 二、注解介绍 注解种类: 1)@Controller 2)@Service 3)@Autowired 4)@RequestMapping 5)@RequestParam 6)@ModelAttribute

Java Spring各种依赖注入注解的区别

Spring对于Bean的依赖注入,支持多种注解方式: 直观上看起来,@Autowired是Spring提供的注解,其他几个都是JDK本身内建的注解,Spring 对这些注解也进行了支持。但是使用起来这三者到底有什么区别呢?笔者经过方法的测试,发现一些有意思的特性。 区别总结如下: 一、@Autowired有个required属性,可以配置为false,这种情况下如果没有找到对应的bean 是不会抛异常的。@Inject和@Resource没有提供对应的配置,所以必须找到否则会抛异常。 二、@Autowired和@Inject基本是一样的,因为两者都是使用AutowiredAnnotationBeanPostProcessor来处理依赖注入。但是@Resource是个例外,它使用的是CommonAnnotationBeanPostProcessor来处理依赖注入。当然,两者都是BeanPostProcessor。

TIPS Qualified name VS Bean name 在Spring设计中,Qualified name并不等同于Bean name,后者必须是唯一的,但是前者类似于tag或者group的作用,对特定的bean进行分类。可以达到getByTag(group)的效果。对于XML配置的bean,可以通过id属性指定bean name(如果没有指定,默认使用类名首字母小写),通过标签指定qualifier name: 如果是通过注解方式,那么可以通过@Qualifier注解指定qualifier name,通过@Named或者@Component(@Service,@Repository等)的value值指定bean name:

SpringMVC常用注解说明

SpringMVC常用注解: 1、@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。在SpringMVC 中提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是Controller ,然后使用@RequestMapping 和@RequestParam 等一些注解用以定义URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。此外Controller 不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet 对象,它们可以通过Controller 的方法参数灵活的获取到。 @Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了 @RequestMapping 注解。@Controller 只是定义了一个控制器类,而使用 @RequestMapping 注解的方法才是真正处理请求的处理器。单单使用@Controller 标记在一个类上还不能真正意义上的说它就是SpringMVC 的一个控制器类,因为这个时候Spring 还不认识它。那么要如何做Spring 才能认识它呢?这个时候就需要我们把这个控制器类交给Spring 来管理。有两种方式: (1)在SpringMVC 的配置文件中定义MyController 的bean 对象。 (2)在SpringMVC 的配置文件中告诉Spring 该到哪里去找标记为@Controller 的Controller 控制器。

spring注解详细介绍

使用Spring2.5的Autowired实现注释型的IOC 161641 使用Spring2.5的新特性——Autowired可以实现快速的自动注入,而无需在xml文档里面添加bean的声明,大大减少了xml文档的维护。(偶喜欢这个功能,因为偶对xml不感冒)。以下是一个例子: 先编写接口Man: public interface Man { public String sayHello(); } 然后写Man的实现类Chinese和American: @Service public class Chinese implements Man{ public String sayHello() { return "I am Chinese!"; } } @Service public class American implements Man{ public String sayHello() { return "I am American!"; } } @Service注释表示定义一个bean,自动根据bean的类名实例化一个首写字母为小写的bean,例如Chinese实例化为chinese,American实例化为american,如果需要自己改名字则:@Service("你自己改的bean名")。 beans.xml 在spring的配置文件里面只需要加上,可以使用base-package="*"表示全部的类。 编写主类测试: @Service public class Main {

spring注解注入示例详解

一、各种注解方式 1.@Autowired注解(不推荐使用,建议使用@Resource) @Autowired可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。 @Autowired的标注位置不同,它们都会在Spring在初始化这个bean时,自动装配这个属性。要使@Autowired能够工作,还需要在配置文件中加入以下 Xml代码 1. 2. @Qualifier注解 @Autowired是根据类型进行自动装配的。例如,如果当Spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。我们可以使用 @Qualifier配合@Autowired来解决这些问题。如下: 1). 可能存在多个UserDao实例 Java代码 1.@Autowired 2.@Qualifier("userServiceImpl") 3.public IUserService userService; 或者 Java代码 1.@Autowired 2.public void setUserDao(@Qualifier("userDao") UserDao userDao) { https://www.360docs.net/doc/f717254303.html,erDao = userDao; 4.} 这样,Spring会找到id为userServiceImpl和userDao的bean进行装配。 2). 可能不存在UserDao实例 Java代码 1.@Autowired(required = false) 2.public IUserService userService;

Spring注解的参数

Spring注解的参数 二、Spring2.5引入注解式处理器支持,通过@Controller和@RequestMapping注解定义我们的处理器类。并且提供了一组强大的注解: 需要通过处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter来开启支持@Controller和@RequestMapping注解的处理器。 @Controller:用于标识是处理器类; @RequestMapping:请求到处理器功能方法的映射规则; @RequestParam:请求参数到处理器功能处理方法的方法参数上的绑定;@RequestParam是传参数的

@ModelAttribute:请求参数到命令对象的绑定; @SessionAttributes:用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session 中; @InitBinder:自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型; 三、Spring3.0引入RESTful架构风格支持(通过@PathVariable注解和一些其他特性支持),且又引入了更多的注解支持: @CookieValue:cookie数据到处理器功能处理方法的方法参数上的绑定; @RequestHeader:请求头(header)数据到处理器功能处理方法的方法参数上的绑定; @RequestBody:请求的body体的绑定(通过HttpMessageConverter进行类型转换); @ResponseBody:处理器功能处理方法的返回值作为响应体(通过HttpMessageConverter进行类型转换);

SpringMVC注解及实现页面跳转详解

Spring MVC 第一讲:SpringMVC页面跳转实例,通过请求访问start.jsp页面 1.1加包 1.2web.xml springMVC org.springframework.web.servlet.Dispatche rServlet 1 springMVC *.do abc 1.3建springMVC-servlet.xml(注:spring默认要求建立在WEB-INF目录下,并且名称为servlet-name_servlet.xml

Spring常用注解汇总

传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop、事物,这么做有两个缺点: 1、如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大;如果按需求分开.xml文件,那么.xml文件又会非常多。总之这将导致配置文件的可读性与可维护性变得很低。 2、在开发中在.java文件和.xml文件之间不断切换,是一件麻烦的事,同时这种思维上的不连贯也会降低开发的效率。 为了解决这两个问题,Spring引入了注解,通过"@XXX"的方式,让注解与Java Bean紧密结合,既大大减少了配置文件的体积,又增加了Java Bean的可读性与内聚性。 不使用注解: 先看一个不使用注解的Spring示例,在这个示例的基础上,改成注解版本的,这样也能看出使用与不使用注解之间的区别,先定义一个老虎: package com.spring.model; public class Tiger { private String tigerName="TigerKing"; public String toString(){ return "TigerName:"+tigerName; } } 再定义一个猴子: package com.spring.model; public class Monkey { private String monkeyName = "MonkeyKing";

public String toString(){ return "MonkeyName:" + monkeyName; } } 定义一个动物园: package com.spring.model; public class Zoo { private Tiger tiger; private Monkey monkey; public Tiger getTiger() { return tiger; } public void setTiger(Tiger tiger) { this.tiger = tiger; } public Monkey getMonkey() { return monkey; } public void setMonkey(Monkey monkey) { this.monkey = monkey; } public String toString(){ return tiger + "\n" + monkey; } } spring的配置文件这么写:

spring注解使用

1.使用Spring注解来注入属性 1.1.使用注解以前我们是怎样注入属性的 类的实现: Java代码 1public class UserManagerImpl implements UserManager{ 2private UserDao userDao; 3public void setUserDao(UserDao userDao){ https://www.360docs.net/doc/f717254303.html,erDao=userDao; 5} 6... 7} 配置文件: Java代码 8 9 10 11 12 13

1.2.引入@Autowired注解(不推荐使用,建议使用@Resource) 类的实现(对成员变量进行标注) Java代码 14public class UserManagerImpl implements UserManager{ 15@Autowired 16private UserDao userDao; 17... 18} 或者(对方法进行标注) Java代码 19public class UserManagerImpl implements UserManager{ 20private UserDao userDao; 21@Autowired 22public void setUserDao(UserDao userDao){ https://www.360docs.net/doc/f717254303.html,erDao=userDao; 24} 25... 26} 配置文件 Java代码 27 28

spring注解详解

概述 注释配置相对于XML 配置具有很多的优势: ?它可以充分利用Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。如使用JPA 注释配置ORM 映射时,我们就不需要指定PO 的属性 名、类型等信息,如果关系表字段和PO 属性名、类型都一致,您甚至无需编 写任务属性映射信息——因为这些信息都可以通过Java 反射机制获取。 ?注释和Java 代码位于一个文件中,而XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和Java 代码放在一起, 有助于增强程序的内聚性。而采用独立的XML 配置文件,程序员在编写一个功 能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低 开发效率。 package com.baobaotao; public class Office { private String officeNo =”001”; //省略 get/setter @Override public String toString() { return "officeNo:" + officeNo; } } Car 拥有两个属性:

清单2. Car.java package com.baobaotao; public class Car { private String brand; private double price; // 省略 get/setter @Override public String toString() { return "brand:" + brand + "," + "price:" + price; } } Boss 拥有Office 和Car 类型的两个属性: 清单3. Boss.java package com.baobaotao; public class Boss { private Car car; private Office office; // 省略 get/setter @Override public String toString() { return "car:" + car + "\n" + "office:" + office; } } 我们在Spring 容器中将Office 和Car 声明为Bean,并注入到Boss Bean 中:下面是使用传统XML 完成这个工作的配置文件beans.xml: 清单4. beans.xml 将以上三个类配置成Bean

SpringMVC中常用的注解

SpringMVC 中常用的注解 spring 从2.5版本开始在编程中引入注解,用户可以使用@RequestMapping , @RequestParam , @ModelAttribute 等等这样类似的注解。到目前为止,Spring 的版本虽然发生了很大的变化,但注解的特性却是一直延续下来,并不断扩展,让广大的开发人员的双手变的更轻松起来,这都离不开Annotation 的强大作用,今天我们就一起来看看Spring MVC 4中常用的那些注解吧。 1. @Controller Controller 控制器是通过服务接口定义的提供访问应用程序的一种行为,它解释用户的输入,将其转换成一个模型然后将试图呈献给用户。Spring MVC 使用 @Controller 定义控制器,它还允许自动检测定义在类路径下的组件并自动注册。如想自动检测生效,需在XML 头文件下引入 spring-context: 1 2 3 4 5 6 7 8 9 10 11 1 2

spring注解使用规范

4.Spring相关编码规范 4.1 Spring 注解使用规范 (1)注入依赖对象: 使用@Resource ,不使用@Autowired (2)将组件纳入Spring容器管理: 使用@Service、@Controller、@Repository,不使用@Component @Controller注解的使用规范:只能应用于action @Scope("prototype") @Controller @SuppressWarnings("serial") public class ExamUserSaveAction extends ActionSupport { @Resource private ExamUserService examUserService; } @Service注解的使用规范:只能应用于service 有接口时规范如下: @Service("examUserService") public class ExamUserServiceImpl implements ExamUserService { … } 无接口时规范如下: @Service public class ExamUserService { … } @Repository注解:由于目前各工程DAO依赖于spring对ibatis的支持,暂时不使用此注解。 (3) service/dao 无接口时,服务层代码放置到cn.xxt.功能名.service/dao包下。 备注:要尽量避免在老功能优化中直接写实现,去掉接口。因为这样的话,老功能中service/dao包下,将会含有接口和类。在做新功能时,可以考虑不使用接口。 4.2 配置文件编写规范 (1)打开自动扫描classpath下特定注解文件的的开关与注入依赖对象的开关 frameworkconfig/spring/root.xml文件中打开{自动扫描组件配置}:

spring框架的注解

@Repository、@Service、@Controller 和@Component @Repository、@Service、@Controller 和@Component 将类标识为Bean Spring 自2.0 版本开始,陆续引入了一些注解用于简化Spring 的开发。@Repository注解便属于最先引入的一批,它用于将数据访问层(DAO 层) 的类标识为Spring Bean。具体只需将该注解标注在DAO类上即可。同时,为了让Spring 能够扫描类路径中的类并识别出@Repository 注解,需要在XML 配置文件中启用Bean 的自动扫描功能,这可以通过实现。如下所示: // 首先使用 @Repository 将 DAO 类声明为 Bean package bookstore.dao; @Repository public class UserDaoImpl implements UserDao{ …… } // 其次,在 XML 配置文件中启动 Spring 的自动扫描功能 …… …… 如此,我们就不再需要在XML 中显式使用 进行Bean 的配置。Spring 在容器初始化时将自动扫描base-package 指定的包及其子包下的所有class文件,所有标注了@Repository 的类都将被注册为Spring Bean。 为什么@Repository 只能标注在DAO 类上呢?这是因为该注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为Spring 的数据访问异常类型。Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。 Spring 2.5 在@Repository的基础上增加了功能类似的额外三个注解:@Component、@Service、@Constroller,它们分别用于软件系统的不同层次: ?@Component 是一个泛化的概念,仅仅表示一个组件(Bean) ,可以作用在任何层次。 ?@Service 通常作用在业务层,但是目前该功能与@Component 相同。

spring注解的学习

Spring注解学习手札(一)构建简单Web应用 文章分类:Java编程 近来工作发生了一些变化,有必要学习一下Spring注解了! 网上找了一些个例子,总的说来比较土,大多数是转载摘抄,按照提示弄下来根本都运行不了,索性自己趟一遍这浑水,在这里留下些个印记。 这次,先来构建一个极为简单的web应用,从controller到dao。不考虑具体实现,只是先对整体架构有一个清晰的了解。日后在分层细述每一层的细节。 相关参考: Spring注解学习手札(一)构建简单Web应用 Spring注解学习手札(二)控制层梳理 Spring注解学习手札(三)表单页面处理 Spring注解学习手札(四)持久层浅析 Spring注解学习手札(五)业务层事务处理 Spring注解学习手札(六)测试 我们将用到如下jar包: 引用 aopalliance-1.0.jar commons-logging-1.1.1.jar log4j-1.2.15.jar spring-beans-2.5.6.jar spring-context-2.5.6.jar spring-context-support-2.5.6.jar spring-core-2.5.6.jar spring-tx-2.5.6.jar spring-web-2.5.6.jar spring-webmvc-2.5.6.jar 先看web.xml Xml代码

java注解详解

JA V A 注解的几大作用及使用方法详解 注解(Annotation) 1、Annotation的工作原理: JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型。该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的class 文件和一个注解处理工具组成。 Annotation并不直接影响代码的语义,但是他可以被看做是程序的工具或者类库。它会反过来对正在运行的程序语义有所影响。 Annotation可以从源文件、class文件或者在运行时通过反射机制多种方式被读取。 常见的作用 有以下几种: 1,生成文档。这是最常见的,也是java 最早提供的注解。 常用的有@see @param @return 等 2,跟踪代码依赖性,实现替代配置文件功能。 比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。 3,在编译时进行格式检查。 如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。 *@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。 *方法的名称就是参数的名称,返回值类型就是参数的类型。 *可以通过default来声明参数的默认值。 父类,接口 https://www.360docs.net/doc/f717254303.html,ng.annotation 包https://www.360docs.net/doc/f717254303.html,ng.annotation 中包含所有已定义或自定义注解所需用到的原注解和接口。如接口https://www.360docs.net/doc/f717254303.html,ng.annotation.Annotation 是所有注解继承的接口,并且是自动继承,不需要定义时指定,类似于所有类都自动继承Object。 该包同时定义了四个元注解;

Spring自动装配与扫描注解代码详解

Spring自动装配与扫描注解代码详解 1 javabean的自动装配 自动注入,减少xml文件的配置信息。 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

2 spring的扫描注解 使用spring的扫描注解,重构三层结构。配置更少的内容 在applicationContext.xml文件中,导入扫描的xsd l 开启注解扫描 ? 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5

相关主题
相关文档
最新文档