当前位置:文档之家› spring注解的学习

spring注解的学习

spring注解的学习
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代码

xmlns:xsi="https://www.doczj.com/doc/de7793406.html,/2001/XMLSchema-instance"

xmlns="https://www.doczj.com/doc/de7793406.html,/xml/ns/javaee"

xmlns:web="https://www.doczj.com/doc/de7793406.html,/xml/ns/javaee/web-app_2_5.xsd"

xsi:schemaLocation="https://www.doczj.com/doc/de7793406.html,/xml/ns/javaee

https://www.doczj.com/doc/de7793406.html,/xml/ns/javaee/web-app_2_5.xsd"

id="WebApp_ID"

version="2.5">

spring

webAppRootKey

spring.webapp.root

log4jConfigLocation

classpath:log4j.xml

log4fRefreshInterval

60000

contextConfigLocation

/WEB-INF/applicationContext.xml

CharacterEncodingFilter

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF-8

forceEncoding

true

CharacterEncodingFilter

/*

org.springframework.web.context.ContextLoaderListener

org.springframework.web.util.Log4jConfigListener

spring

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

/WEB-INF/servlet.xml

spring

*.do

index.html

index.htm

index.jsp

default.html

default.htm

default.jsp

xmlns:xsi="https://www.doczj.com/doc/de7793406.html,/2001/XMLSchema-instance"

xmlns="https://www.doczj.com/doc/de7793406.html,/xml/ns/javaee"

xmlns:web="https://www.doczj.com/doc/de7793406.html,/xml/ns/javaee/web-app_2_5.xsd"

xsi:schemaLocation="https://www.doczj.com/doc/de7793406.html,/xml/ns/javaee

https://www.doczj.com/doc/de7793406.html,/xml/ns/javaee/web-app_2_5.xsd"

id="WebApp_ID"

version="2.5">

spring

webAppRootKey

spring.webapp.root

log4jConfigLocation

classpath:log4j.xml

log4fRefreshInterval

60000

contextConfigLocation

/WEB-INF/applicationContext.xml

CharacterEncodingFilter

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF-8

forceEncoding

true

CharacterEncodingFilter

/*

org.springframework.web.context.ContextLoaderListener

org.springframework.web.util.Log4jConfigListener

spring

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

/WEB-INF/servlet.xml

spring

*.do

index.html

index.htm

index.jsp

default.html

default.htm

default.jsp

有不少人问我,这段代码是什么:

Xml代码

webAppRootKey

spring.webapp.root

webAppRootKey

spring.webapp.root

这是当前应用的路径变量,也就是说你可以在其他代码中使用${spring.webapp.root}指代当前应用路径。我经常用它来设置log的输出目录。

为什么要设置参数log4jConfigLocation?

Xml代码

log4jConfigLocation

classpath:log4j.xml

log4fRefreshInterval

60000

log4jConfigLocation

classpath:log4j.xml

log4fRefreshInterval

60000

这是一种基本配置,spring中很多代码使用了不同的日志接口,既有log4j也有commons-logging,这里只是强制转换为log4j!并且,log4j的配置文件只能放在classpath 根路径。同时,需要通过commons-logging配置将日志控制权转交给log4j。同时commons-logging.properties必须放置在classpath根路径。

commons-logging内容:

Properties代码

https://www.doczj.com/doc/de7793406.html,mons.logging.Log=https://www.doczj.com/doc/de7793406.html,mons.logging.impl.Log4JLogger

https://www.doczj.com/doc/de7793406.html,mons.logging.Log=https://www.doczj.com/doc/de7793406.html,mons.logging.impl.Log4JLogger

最后,记得配置log4j的监听器:

Xml代码

org.springframework.web.util.Log4jConfigListener

org.springframework.web.util.Log4jConfigListener

接下来,我们需要配置两套配置文件,applicationContext.xml和servlet.xml。applicationContext.xml用于对应用层面做整体控制。按照分层思想,统领service层和dao 层。servlet.xml则单纯控制controller层。

Xml代码

xmlns="https://www.doczj.com/doc/de7793406.html,/schema/beans"

xmlns:xsi="https://www.doczj.com/doc/de7793406.html,/2001/XMLSchema-instance"

xmlns:context="https://www.doczj.com/doc/de7793406.html,/schema/context"

xsi:schemaLocation="https://www.doczj.com/doc/de7793406.html,/schema/beans

https://www.doczj.com/doc/de7793406.html,/schema/beans/spring-beans.xsd

https://www.doczj.com/doc/de7793406.html,/schema/context

https://www.doczj.com/doc/de7793406.html,/schema/context/spring-context.xsd">

resource="service.xml"/>

resource="dao.xml"/>

xmlns="https://www.doczj.com/doc/de7793406.html,/schema/beans"

xmlns:xsi="https://www.doczj.com/doc/de7793406.html,/2001/XMLSchema-instance"

xmlns:context="https://www.doczj.com/doc/de7793406.html,/schema/context"

xsi:schemaLocation="https://www.doczj.com/doc/de7793406.html,/schema/beans

https://www.doczj.com/doc/de7793406.html,/schema/beans/spring-beans.xsd

https://www.doczj.com/doc/de7793406.html,/schema/context

https://www.doczj.com/doc/de7793406.html,/schema/context/spring-context.xsd">

resource="service.xml"/>

resource="dao.xml"/>

applicationContext.xml什么都不干,它只管涉及到整体需要的配置,并且集中管理。这里引入了两个配置文件service.xml和dao.xml分别用于业务、数据处理。service.xml

Xml代码

xmlns="https://www.doczj.com/doc/de7793406.html,/schema/beans"

xmlns:xsi="https://www.doczj.com/doc/de7793406.html,/2001/XMLSchema-instance"

xmlns:context="https://www.doczj.com/doc/de7793406.html,/schema/context"

xsi:schemaLocation="https://www.doczj.com/doc/de7793406.html,/schema/beans

https://www.doczj.com/doc/de7793406.html,/schema/beans/spring-beans.xsd

https://www.doczj.com/doc/de7793406.html,/schema/context

https://www.doczj.com/doc/de7793406.html,/schema/context/spring-context.xsd">

base-package="org.zlex.spring.service"/>

xmlns="https://www.doczj.com/doc/de7793406.html,/schema/beans"

xmlns:xsi="https://www.doczj.com/doc/de7793406.html,/2001/XMLSchema-instance"

xmlns:context="https://www.doczj.com/doc/de7793406.html,/schema/context"

xsi:schemaLocation="https://www.doczj.com/doc/de7793406.html,/schema/beans

https://www.doczj.com/doc/de7793406.html,/schema/beans/spring-beans.xsd

https://www.doczj.com/doc/de7793406.html,/schema/context

https://www.doczj.com/doc/de7793406.html,/schema/context/spring-context.xsd">

base-package="org.zlex.spring.service"/>

注意,这里通过标签指定了业务层的基础包路径——“org.zlex.spring.service”。也就是说,业务层相关实现均在这一层。这是有必要的分层之一。

dao.xml

Xml代码

xmlns="https://www.doczj.com/doc/de7793406.html,/schema/beans"

xmlns:xsi="https://www.doczj.com/doc/de7793406.html,/2001/XMLSchema-instance"

xmlns:aop="https://www.doczj.com/doc/de7793406.html,/schema/aop"

xmlns:context="https://www.doczj.com/doc/de7793406.html,/schema/context"

xmlns:tx="https://www.doczj.com/doc/de7793406.html,/schema/tx"

xsi:schemaLocation="https://www.doczj.com/doc/de7793406.html,/schema/beans

https://www.doczj.com/doc/de7793406.html,/schema/beans/spring-beans.xsd

https://www.doczj.com/doc/de7793406.html,/schema/aop

https://www.doczj.com/doc/de7793406.html,/schema/aop/spring-aop.xsd

https://www.doczj.com/doc/de7793406.html,/schema/context

https://www.doczj.com/doc/de7793406.html,/schema/context/spring-context.xsd

https://www.doczj.com/doc/de7793406.html,/schema/tx

https://www.doczj.com/doc/de7793406.html,/schema/tx/spring-tx.xsd">

base-package="org.zlex.spring.dao"/>

xmlns="https://www.doczj.com/doc/de7793406.html,/schema/beans"

xmlns:xsi="https://www.doczj.com/doc/de7793406.html,/2001/XMLSchema-instance"

xmlns:aop="https://www.doczj.com/doc/de7793406.html,/schema/aop"

xmlns:context="https://www.doczj.com/doc/de7793406.html,/schema/context"

xmlns:tx="https://www.doczj.com/doc/de7793406.html,/schema/tx"

xsi:schemaLocation="https://www.doczj.com/doc/de7793406.html,/schema/beans

https://www.doczj.com/doc/de7793406.html,/schema/beans/spring-beans.xsd

https://www.doczj.com/doc/de7793406.html,/schema/aop

https://www.doczj.com/doc/de7793406.html,/schema/aop/spring-aop.xsd

https://www.doczj.com/doc/de7793406.html,/schema/context

https://www.doczj.com/doc/de7793406.html,/schema/context/spring-context.xsd

https://www.doczj.com/doc/de7793406.html,/schema/tx

https://www.doczj.com/doc/de7793406.html,/schema/tx/spring-tx.xsd">

base-package="org.zlex.spring.dao"/>

dao层如法炮制,包路径是"org.zlex.spring.dao"。从这个角度看,注解还是很方便的!

最后,我们看看servlet.xml

Xml代码

xmlns="https://www.doczj.com/doc/de7793406.html,/schema/beans"

xmlns:xsi="https://www.doczj.com/doc/de7793406.html,/2001/XMLSchema-instance"

xmlns:context="https://www.doczj.com/doc/de7793406.html,/schema/context"

xsi:schemaLocation="https://www.doczj.com/doc/de7793406.html,/schema/beans

https://www.doczj.com/doc/de7793406.html,/schema/beans/spring-beans.xsd

https://www.doczj.com/doc/de7793406.html,/schema/context

https://www.doczj.com/doc/de7793406.html,/schema/context/spring-context.xsd">

base-package="org.zlex.spring.controller"/>

id="urlMapping"

class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>

class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

xmlns="https://www.doczj.com/doc/de7793406.html,/schema/beans"

xmlns:xsi="https://www.doczj.com/doc/de7793406.html,/2001/XMLSchema-instance"

xmlns:context="https://www.doczj.com/doc/de7793406.html,/schema/context"

xsi:schemaLocation="https://www.doczj.com/doc/de7793406.html,/schema/beans

https://www.doczj.com/doc/de7793406.html,/schema/beans/spring-beans.xsd

https://www.doczj.com/doc/de7793406.html,/schema/context

https://www.doczj.com/doc/de7793406.html,/schema/context/spring-context.xsd">

base-package="org.zlex.spring.controller"/>

id="urlMapping"

class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping "/>

class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"

/>

包路径配置就不细说了,都是一个概念。最重要的时候后面两个配置,这将使得注解生效!“org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping”是默认实现,可以不写,Spring容器默认会默认使用该类。

“org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter”直接关系到多动作控制器配置是否可用!

简单看一下代码结构,如图:

Account类是来存储账户信息,属于域对象,极为简单,代码如下所示:

Account.java

Java代码

/**

*2010-1-23

*/

package org.zlex.spring.domain;

import java.io.Serializable;

/**

*

*@author梁栋

*@version1.0

*@since1.0

*/

public class Account implements Serializable{

/**

*

*/

private static final long serialVersionUID=-533698031946372178L;

private String username;

private String password;

/**

*@param username

*@param password

*/

public Account(String username,String password){

https://www.doczj.com/doc/de7793406.html,ername=username;

this.password=password;

}

/**

*@return the username

*/

public String getUsername(){

return username;

}

/**

*@param username the username to set

*/

public void setUsername(String username){

https://www.doczj.com/doc/de7793406.html,ername=username;

}

/**

*@return the password

*/

public String getPassword(){

return password;

}

/**

*@param password the password to set

*/

public void setPassword(String password){

this.password=password;

}

}

/**

*2010-1-23

*/

package org.zlex.spring.domain;

import java.io.Serializable;

/**

*

*@author梁栋 *@version1.0

*@since1.0

*/

public class Account implements Serializable{

/**

*

*/

private static final long serialVersionUID=-533698031946372178L;

private String username;

private String password;

/**

*@param username

*@param password

*/

public Account(String username,String password){

https://www.doczj.com/doc/de7793406.html,ername=username;

this.password=password;

}

/**

*@return the username

*/

public String getUsername(){

return username;

}

/**

*@param username the username to set

*/

public void setUsername(String username){

https://www.doczj.com/doc/de7793406.html,ername=username;

}

/**

*@return the password

*/

public String getPassword(){

return password;

}

/**

*@param password the password to set

*/

public void setPassword(String password){

this.password=password;

}

}

通常,在构建域对象时,需要考虑该对象可能需要进行网络传输,本地缓存,因此建议实现序列化接口Serializable

我们再来看看控制器,这就稍微复杂了一点代码如下所示:

AccountController.java

Java代码

/**

*2010-1-23

*/

package org.zlex.spring.controller;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

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

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.ServletRequestUtils;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.zlex.spring.service.AccountService;

/**

*

*@author梁栋

*@version1.0

*@since1.0

*/

@Controller

@RequestMapping("/account.do")

public class AccountController{

@Autowired

private AccountService accountService;

@RequestMapping(method=RequestMethod.GET)

public void hello(HttpServletRequest request,HttpServletResponse response)

throws Exception{

String username=ServletRequestUtils.getRequiredStringParameter(

request,"username");

String password=ServletRequestUtils.getRequiredStringParameter(

request,"password");

System.out.println(accountService.verify(username,password));

}

}

/**

*2010-1-23

*/

package org.zlex.spring.controller;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

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

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.ServletRequestUtils;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.zlex.spring.service.AccountService;

/**

*

*@author梁栋

*@version1.0

*@since1.0

*/

@Controller

@RequestMapping("/account.do")

public class AccountController{

@Autowired

private AccountService accountService;

@RequestMapping(method=RequestMethod.GET)

public void hello(HttpServletRequest request,HttpServletResponse response) throws Exception{

String username=ServletRequestUtils.getRequiredStringParameter(

request,"username");

String password=ServletRequestUtils.getRequiredStringParameter(

request,"password");

System.out.println(accountService.verify(username,password));

}

}

分段详述:

Java代码

@Controller

@RequestMapping("/account.do")

@Controller

@RequestMapping("/account.do")

这两行注解,@Controller是告诉Spring容器,这是一个控制器类,@RequestMapping("/account.do")是来定义该控制器对应的请求路径(/account.do)

Java代码

@Autowired

private AccountService accountService;

@Autowired

private AccountService accountService;

这是用来自动织入业务层实现AccountService,有了这个注解,我们就可以不用写setAccountService()方法了!

同时,JSR-250标准注解,推荐使用@Resource来代替Spring专有的@Autowired注解。

引用

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

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

@Resource装配顺序

1.如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常

2.如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常

3.如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常

4.如果既没有指定name,又没有指定type,则自动按照byName方式进行装配(见2);如果没有匹配,则回退为一个原始类型(UserDao)进行匹配,如果匹配则自动装配;

1.6.@PostConstruct(JSR-250)

在方法上加上注解@PostConstruct,这个方法就会在Bean初始化之后被Spring容器执行(注:Bean初始化包括,实例化Bean,并装配Bean的属性(依赖注入))。

这有点像ORM最终被JPA一统天下的意思!大家知道就可以了,具体使用何种标准由项目说了算!

最后,来看看核心方法:

Java代码

@RequestMapping(method=RequestMethod.GET)

public void hello(HttpServletRequest request,HttpServletResponse response)

throws Exception{

String username=ServletRequestUtils.getRequiredStringParameter(

request,"username");

String password=ServletRequestUtils.getRequiredStringParameter(

request,"password");

System.out.println(accountService.verify(username,password));

}

@RequestMapping(method=RequestMethod.GET)

public void hello(HttpServletRequest request,HttpServletResponse response)

throws Exception{

String username=ServletRequestUtils.getRequiredStringParameter(

request,"username");

String password=ServletRequestUtils.getRequiredStringParameter(

request,"password");

System.out.println(accountService.verify(username,password));

}

注解@RequestMapping(method=RequestMethod.GET)指定了访问方法类型。

注意,如果没有用这个注解标识方法,Spring容器将不知道那个方法可以用于处理get请求!对于方法名,我们可以随意定!方法中的参数,类似于“HttpServletRequest request, HttpServletResponse response”,只要你需要方法可以是有参也可以是无参!

解析来看Service层,分为接口和实现:

AccountService.java

Java代码

/**

*2010-1-23

*/

package org.zlex.spring.service;

/**

*

*@author梁栋 *@version1.0

*@since1.0

*/

public interface AccountService{

/**

*验证用户身份

*

*@param username

*@param password

*@return

*/

boolean verify(String username,String password);

}

/**

*2010-1-23

*/

package org.zlex.spring.service;

/**

*

*@author梁栋 *@version1.0

*@since1.0

*/

public interface AccountService{

/**

*验证用户身份

*

*@param username

*@param password

*@return

*/

boolean verify(String username,String password);

}

接口不需要任何Spring注解相关的东西,它就是一个简单的接口!

重要的部分在于实现层,如下所示:

AccountServiceImpl.java

Java代码

/**

*2010-1-23

*/

package org.zlex.spring.service.impl;

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

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import org.zlex.spring.dao.AccountDao;

import org.zlex.spring.domain.Account;

import org.zlex.spring.service.AccountService;

/**

*

*@author梁栋

*@version1.0

*@since1.0

*/

@Service

@Transactional

public class AccountServiceImpl implements AccountService{

@Autowired

private AccountDao accountDao;

/*

*(non-Javadoc)

*

*@see org.zlex.spring.service.AccountService#verify(https://www.doczj.com/doc/de7793406.html,ng.String, *https://www.doczj.com/doc/de7793406.html,ng.String)

*/

@Override

public boolean verify(String username,String password){

Account account=accountDao.read(username);

if(password.equals(account.getPassword())){

return true;

}else{

return false;

}

}

}

/**

*2010-1-23

*/

package org.zlex.spring.service.impl;

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

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import org.zlex.spring.dao.AccountDao;

import org.zlex.spring.domain.Account;

import org.zlex.spring.service.AccountService;

/**

*

*@author梁栋

*@version1.0

*@since1.0

*/

@Service

@Transactional

public class AccountServiceImpl implements AccountService{

@Autowired

private AccountDao accountDao;

/*

*(non-Javadoc)

*

*@see org.zlex.spring.service.AccountService#verify(https://www.doczj.com/doc/de7793406.html,ng.String, *https://www.doczj.com/doc/de7793406.html,ng.String)

*/

@Override

public boolean verify(String username,String password){

Account account=accountDao.read(username);

if(password.equals(account.getPassword())){

return true;

}else{

return false;

}

}

}

注意以下内容:

Java代码

@Service

@Transactional

@Service

@Transactional

注解@Service用于标识这是一个Service层实现,@Transactional用于控制事务,将事务定位在业务层,这是非常务实的做法!

接下来,我们来看持久层:AccountDao和AccountDaoImpl类

AccountDao.java

Java代码

/**

*2010-1-23

*/

package org.zlex.spring.dao;

import org.zlex.spring.domain.Account;

/**

*

*@author梁栋

*@version1.0

*@since1.0

*/

public interface AccountDao{

/**

*读取用户信息

*

*@param username

*@return

Spring考试

1. (单选题)下列关于Spring配置文件的说法不正确的是 o A. Spring默认是读取/WEB-INF/配置文件 o B. Spring的配置文件可以配置在类路径下,并可以重命名,但是需要在文件中指定 o C. 把文件放到src目录下,Spring也可以读到 o D. 可以通过在中的进行指定 Spring配置文件 正确答案:C 把文件放到src目录下,需要在web。xml里设置 contextConfigLocation /WEB-INF/classes/ 可以让spring读到 2. (单选题)下列关于Spring特性中IoC描述错误的是 o A. IoC就是指程序之间的关系由程序代码直接操控 o B. 所谓“控制反转”是指控制权由应用代码转到外部容器,即控制权的转移 o C. IoC将控制创建的职责搬进了框架中,从应用代码脱离开来 o D. 使用Spring的IoC容器时只需指出组件需要的对象,在运行时Spring的IoC 容器会根据XML配置数据提供给它

正确答案:A IOC是来完成相互依赖的对象的创建、协调工作。 3. (单选题)下列关于Spring的装配模式(default-autowire)描述不正确的是 o A. Spring中,至少有两种装配模式,按“类型”和“名字” o B. Spring中默认是按名字进行装配的 o C. 可以用default-autowire=”byType”配置按类型装配 o D. 一旦在一个Spring配置文件中配置了default-autowire=”byType”,其它的配置文件也是按此种装配方式进行装配 正确答案:D 在标签中指定default-autowire属性,那么对于子标签 如果没有单独的设置autowire属性,那么将采用父标签 的default-autowire属性的模式,如果单独设置了autowire 属性,则采用自己的模式 4. (单选题)下列选项关于Spring的核心机制——依赖注入的描述正确的是 o A. 所谓依赖注入就是明确地定义组件接口,独立开发各个组件,然后根据组件间的依赖关系组装运行的设计开发模式 o B. Spring不负责管理bean之间的关系 o C. 节点有可选的子节点,用于注入bean的属性 o D. 在Spring的配置文件中,使用来创建Bean的实例 正确答案:B Spring通过一个配置文件描述Bean及Bean之间的依赖关系,利用java语言的反射功能实例化Bean并建立Bean之间的依赖关系。spring的ioc容器在完成这些底层工作的基础上,还提供了bean实例缓存,生命周期管理,bean实例代理,事件发布,资源装载等高级服务 5.

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 注释。

SpringMVC配置的基本步骤

Springmvc框架配置步骤 小弟是个新手,有不对的地方请tell me,一起研究探讨。谢谢。 1062140832@https://www.doczj.com/doc/de7793406.html, 配置springmvc框架其实不是很难,要现有一个总体的认识,确定要分几步,每一步主要是干什么,不要太盲目。 以为web.xml是项目的入口,所以所有的配置文件,都必须引入到wem.xml中,不然,配置了等于没用。所以,要先从入口入手。 配置web.xml 1、首先引入springmvc-servlet.xml文件 springMVC org.springframework.web.servlet.DispatcherServlet contextConfigLocation /WEB-INF/spring/mvc/springmvc-servlet.xml 1 2、将spring加载到web.xml中 org.springframework.web.context.ContextLoaderListener 3、配置上下文路径 contextConfigLocation /WEB-INF/spring/spring.xml,/WEB-INF/spring/spring-*.xml 说明:如果有很多的关于spring的配置文件,建议分开写,比如事务一个文件(spring-transaction.xml),springmvc-hibernate.xml一个配置文件,这样方便读写。

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

SpringMVC深入总结

一、前言: 大家好,Spring3 MVC是非常优秀的MVC框架,由其是在3.0版本发布后,现在有越来越多的团队选择了Spring3 MVC了。Spring3 MVC结构简单,应了那句话简单就是美,而且他强大不失灵活,性能也很优秀。 官方的下载网址是:https://www.doczj.com/doc/de7793406.html,/download(本文使用是的Spring 3.0.5版本) Struts2也是比较优秀的MVC构架,优点非常多比如良好的结构。但这里想说的是缺点,Struts2由于采用了值栈、OGNL表达式、struts2标签库等,会导致应用的性能下降。Struts2的多层拦截器、多实例action性能都很好。可以参考我写的一篇关于Spring MVC与Struts2与Servlet比较的文章https://www.doczj.com/doc/de7793406.html,/admin/blogs/698217 Spring3 MVC的优点: 1、Spring3 MVC的学习难度小于Struts2,Struts2用不上的多余功能太多。呵呵,当然这不是决定因素。 2、Spring3 MVC很容易就可以写出性能优秀的程序,Struts2要处处小心才可以写出性能优秀的程序(指MVC部分) 3、Spring3 MVC的灵活是你无法想像的,Spring的扩展性有口皆碑,Spring3 MVC当然也不会落后,不会因使用了MVC框架而感到有任何的限制。 Struts2的众多优点:略... (呵呵,是不是不公平?) 众多文章开篇时总要吹些牛,吸引一下读者的眼球,把读者的胃口调起来,这样大家才有兴趣接着往后看。本文也没能例外。不过保证你看了之后不会后悔定有收获。

spring使用基于注解的AOP事务管理

spring使用基于注解的AOP事务管理 16.6 AOP事务管理 AOP事务管理利用了Spring AOP的基础设施,在大多数情况下,Spring AOP会创建一个JDK代理以拦截方法调用。你可以使用装载时编织以在装载期编织切面,这样就不需要代理了(如果你记不清什么是装载时编织,请参看第6章)。你有两种方式来配置Spring AOP 事务管理,基于注解的配置以及XML配置。 16.6.1 使用基于注解的AOP事务管理 你可以借助于AOP的自动代理,通过注解将事务性行为引入到现有的bean中。让我们以代码清单16-21开始吧,它展示了类DeclarativeTxBankService。 代码清单16-21 DeclarativeTxBankService实现 请注意@Transactional属性,为了让Spring的事务管理基础设施可以利用该属性创建恰当的切入点和通知,我们需要使用AOP的自动代理和注解驱动的事务支持。代码清单16-22展示了与该注解相对应的XML配置。 代码清单16-22 基于注解的事务管理的配置文件

该XML配置文件展示了标准的bankService bean声明,紧跟其后的是 标签。 标签使用@Transactional注解创建恰当的事务管理切面。接下来由通知匹配的bean。 1.探索tx:annotation-driven标签 标签是注解驱动的事务管理支持的核心。表16-3列出了 标签的所有属性。 表16-3 标签的属性 属性说明 transactionManager 指定到现有的PlatformTransaction Manager bean的引用,通知会使用该引用 mode 指定Spring事务管理框架创建通知bean的方式。 可用的值有proxy和aspectj。前者是默认值, 表示通知对象是个JDK代理;后者表示 Spring AOP会使用AspectJ创建代理 order 指定创建的切面的顺序。只要目标对象有多个通知就可以使用该属性 proxy-target-class 该属性如果为true就表示你想要代理目标类而不是bean所实现的所有接口

基于注解的Spring AOP的配置和使用

基于注解的Spring AOP的配置和使用 AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程。可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。 AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。 我们现在做的一些非业务,如:日志、事务、安全等都会写在业务代码中(也即是说,这些非业务类横切于业务类),但这些代码往往是重复,复制——粘贴式的代码会给程序的维护带来不便,AOP就实现了把这些业务需求与系统需求分开来做。这种解决的方式也称代理机制。 先来了解一下AOP的相关概念,《Spring参考手册》中定义了以下几个AOP的重要概念,结合以上代码分析如下: ?切面(Aspect):官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”,在本例中,“切面”就是类TestAspect所关注的具体行为,例如,AServiceImpl.barA()的调用就是切面TestAspect所关注的行为之一。“切面”在ApplicationContext 中来配置。 ?连接点(Joinpoint):程序执行过程中的某一行为,例如,UserService.get 的调用或者UserService.delete抛出异常等行为。 ?通知(Advice):“切面”对于某个“连接点”所产生的动作,例如,TestAspect 中对com.spring.service包下所有类的方法进行日志记录的动作就是一个Advice。其中,一个“切面”可以包含多个“Advice”,例如ServiceAspect。?切入点(Pointcut):匹配连接点的断言,在AOP中通知和一个切入点表达式关联。例如,TestAspect中的所有通知所关注的连接点,都由切入点表达式execution(* com.spring.service.*.*(..))来决定。 ?目标对象(Target Object):被一个或者多个切面所通知的对象。例如,AServcieImpl和BServiceImpl,当然在实际运行时,Spring AOP采用代理实现,实际AOP操作的是TargetObject的代理对象。 ?AOP代理(AOP Proxy):在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。默认情况下,TargetObject实现了接口时,则采用JDK动态代理,例如,AServiceImpl;反之,采用CGLIB代理,例如,BServiceImpl。 强制使用CGLIB代理需要将 的 proxy-target-class属性设为true。 通知(Advice)类型: ?前置通知(Before advice):在某连接点(JoinPoint)之前执行的通知,但这个通知不能阻止连接点前的执行。ApplicationContext中在 里面使用元素进行声明。例如,TestAspect中的doBefore方法。

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

2.Spring-mvc框架结构及执行流程

Spring mvc架构及执行流程一、请求处理流程图 二、执行流程说明 三、组件说明

说明:在springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc 的三大组件。 需要用户编写的组件有handler、view 四、Spring MVC配置 1、组件扫描器:使用组件扫描器省去在spring容器配置每个controller类,使用 自动扫描标记@controller的配置如下:

2、RequestMappingHandlerMapping:注解处理器映射器,对类中标记@RequestMapping 的方法进行映射,根据RequestMapping定义的url匹配RequestMapping标记的方 法,匹配成功返回HandlerMethod对象给前端控制器,HandlerMethod对象中封装 注解描述: @RequestMapping:定义请求url到处理器功能方法的映射 3、RequestMappingHandlerAdapter:注解式处理器适配器,对标记@RequestMapping 的方法进行适配。 从spring3.1版本开始,废除了AnnotationMethodHandlerAdapter的使用,推荐使用 4、:spring mvc 使用自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter,可用在spring-mvc.xml 配置文件总使用替代注解处理器和适配器的配置。 5、视图解析器 InternalResourceViewResolver:支持JSP视图解析 viewClass:JstlView表示JSP模板页面需要使用JSTL标签库,所以classpath中必须包含jstl 的相关jar 包。此属性可以不设置,默认为JstlView。 prefix 和suffix:查找视图页面的前缀和后缀,最终视图的址为:

spring配置和注解开发原理

1、Spring是一个开源、轻量级框架(轻量级是指依赖的东西少) 2、Spring核心控制反转(IoC)和面向切面(AOP)。 ——AOP:面向切面编程,扩展功能时不用修改源代码 ——IOC:创建对象不再是自己new出来,而是交给spring容器管理 3、Spring希望为企业应用提供一站式(one-stopshop)的解决方案。 一站式:从web层到访问数据库层都有相应解决方案。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 对象的创建交给spring管理(基于配置的方式实现、基于注解的方式实现) IOC底层原理:Xml配置、dom4j解析xml、工厂设计模式、反射 工厂模式:将对象的创建交给工厂,使用时调用工厂方法来获取。A需要B时,不是直接创建B,而是通过C的方法来获取,C的方法用来创建B。 注解方式原理:

Spring整合web框架原理 1、把加载配置文件和创建对象的过程,在服务器启动的时候完成。 2、用监听器实现 Spring注解: ————注解是代码里面的特殊标签,使用注解可以完成一定功能; 注解写法@注解名(属性名称=属性值);注解可以用在类上、方法上、属性上。 注解使用: 1、在对应类上加上注解,标明该类的创建交给spring来管理。

2、开启注解扫描功能,要指明扫描哪些包。 3、如果要为属性注入,则在属性上使用@autowired注解 AOP概念: 面向切面编程,扩展功能而不用修改源代码,采用横向抽取机制,取代了传统的纵向继承。 传统的纵向继承,耦合度太高 AOP底层使用动态代理实现:a. 如果是有接口的情况,使用动态代理创建接口实现类代理对象,b.如果没有接口,使用动态代理创建类的子类的代理对象。

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:

spring MVC配置详解

牧涛 --<-<-<@态度决定一切→_→。。。 ?博客园 ?首页 ?新闻 ?新随笔 ?联系 ?管理 ?订阅 随笔- 171 文章- 3 评论- 79 spring MVC配置详解 现在主流的Web MVC框架除了Struts这个主力外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了。不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理。 一、Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0) 1. jar包引入 Spring 2.5.6:spring.jar、spring-webmvc.jar、commons-logging.jar、cglib -nodep-2.1_3.jar Hibernate 3.6.8:hibernate3.jar、hibernate-jpa-2.0-api-1.0.1.Final.jar、a ntlr-2.7.6.jar、commons-collections-3.1、dom4j-1.6.1.jar、javassist-3.12.0.G A.jar、jta-1.1.jar、slf4j-api-1.6.1.jar、slf4j-nop-1.6.4.jar、相应数据库的驱动jar 包 SpringMVC是一个基于DispatcherServlet(分发器)的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请求给相应的Handler,Handler处理以后再返回相应的视图(View)和模型(Model),返回的视图和模型都可以不指定,即可以只返回Model或只返回View或都不返回。 DispatcherServlet是继承自HttpServlet的,既然SpringMVC是基于DispatcherSe rvlet的,那么我们先来配置一下DispatcherServlet,好让它能够管理我们希望它管理的内容。HttpServlet是在web.xml文件中声明的。 spring org.springframework.web.servlet.DispatcherServlet< /servlet-class>