您的位置:首页 > 编程语言 > Java开发

Spring的注解Controller中使用AOP

2015-11-09 10:44 423 查看
本文讲解在基于Controller注解上使用AOP的配置和使用。

1、先看web.xml中的配置

web.xml中主要配置contextConfigLocation和DispatcherServlet。本例中加载classpath下所有以applicationContext-开头的xml配置文件,spring拦截以.shtml结尾的请求并交给DispatcherServlet进行处理。相关的主要配置如下:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-*.xml</param-value>
</context-param>

<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.shtml</url-pattern>
</servlet-mapping>

2、spring-servlet.xml中的配置

spring-servlet.xml中配置controller实体和spring代理方法配置。其中controller实体使用自动扫描指定包下面的@Controller注解实现。实现Controller注解上使用AOP关键配置在于对Spring代理方法的配置,需要指定aop:aspectj-autoproxy proxy-target-class的值为true(即使用cglib代理而不实用jdk代理),且该配置必须存放于该文件中,否则无法生效。相关参考的配置如下:

<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd ">

<!-- 自动扫描注解的Controller -->
<context:component-scan base-package="com.landsem.update.base.controller.impl" />
<context:component-scan base-package="com.landsem.update.base.business" />

<!-- 通知spring使用cglib而不是jdk的来生成代理方法 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!-- <bean id="testAop" class="com.landsem.update.base.aop.TestAop"></bean> -->

<!-- <bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" /> -->
<!-- =================================日志记录====================================== -->
<!-- 处理方法级别上的@RequestMapping注解 ,完成请求和注解POJO的映射-->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<bean class="com.landsem.update.base.aop.LoggerInterception"/> <!-- 用于日志存储 -->
</list>
</property>
</bean>

<!-- 视图解析器策略 和 视图解析器 -->
<!-- 对JSTL提供良好的支持 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 默认的viewClass,可以不用配置 <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"
/> -->
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>


3、AOP的配置

AOP的相关实体配置被存放到applicationContext-aop.xml,方便分开管理。该文件中主要实现扫描指定包下的实体类。该配置参考如下:

<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

<!-- 异常处理器 -->
<!-- =================================异常处理 ====================================== -->
<!-- <bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="errors/error" />
<property name="exceptionMappings">
<props>
<prop key="java.lang.Throwable">errors/error</prop>
</props>
</property>
</bean> -->
<bean id="exceptionHandler" class="com.landsem.update.base.exception.handler.ExceptionDispatcher"/>

<!-- 自动扫描aop -->
<context:component-scan base-package="com.landsem.update.base.aop" />

</beans>

4、AOP的实现demo

例子中将AOP相关实现的实体类存放到com.landsem.update.base.aop包下,在applicationContext-aop.xml中指定了自动扫描该包下实体。

如下为一个简单的实现demo,该demo用于实现对包com.landsem.update.base.controller.impl中SystemUpdateControllerImpl实体类中systemUpdateCheck方法执行前的参数检查,如果参数不符合规则时只需抛出异常即可阻止程序继续运行。demo中使用的几个技术点简要说明如下,更多详细介绍需要自行搜索:

(1)、@Pointcut注解定义一个切入点为checkUpdate;如果需要指定拦截多个Controller中的方法时可参考如下使用格式(使用 ‘||’ 进行连接):

@Pointcut("execution(* com.landsem.update.base.controller.impl.UpdateUpdaterControllerImpl.doPostAction(..)) || execution(* com.landsem.update.base.controller.impl.CustomerControllerImpl.doPostAction(..))")
(2)、@Before注解定义一个在该切入点前面执行的方法;

(3)、@Component注解实现在配置文件中能够自动扫描到该实体类;

(4)、@Aspect注解用于开启切面声明;

(5)、实体类实现Ordered接口,并重载了getOrder方法,用于指定存在多个切面时该切面的执行顺序,值越小越先执行。

package com.landsem.update.base.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import com.landsem.update.base.exception.ParamsFormatErrorException;
import com.landsem.update.http.json.UpdateCheckRequest;
import com.landsem.update.util.FormatCheckUtil;

/**
* This class use to check parameters of client request update check.Throw a
* exception to hold back request when parameters illegal.
*
* @author yingxianFei
*
*/
@Component
@Aspect
public class CheckFormatCheckAop implements Ordered{
protected static Logger logger = Logger
.getLogger(CheckFormatCheckAop.class);

@Pointcut("execution(* com.landsem.update.base.controller.impl.SystemUpdateControllerImpl.systemUpdateCheck(..))")
public void checkUpdate() {

}

@Before("checkUpdate()")
public void beforeCkeckUpdate(JoinPoint joinpoint)
throws ParamsFormatErrorException {
Object[] args = joinpoint.getArgs();
/* for (int i = 0; i < args.length; i++) {
logger.debug("arg[" + i + "]=" + args[i].toString());
}*/
if (2 <= args.length) {
String params = args[1].toString();
UpdateCheckRequest paramFromClient = new UpdateCheckRequest();
if (null != paramFromClient) {
paramFromClient.setAttributeWithJson(params);
if (!FormatCheckUtil.isSystemVersion(paramFromClient
.getAndroid())
|| !FormatCheckUtil.isMcuVersion(paramFromClient
.getMcu())) {
throw new ParamsFormatErrorException(
"request format error.");
}
}
}
//can't get request parameters.
else {
logger.warn("param's lenth is not current");
throw new ParamsFormatErrorException(
"request format error.");
}
}

@Override
public int getOrder() {
return 0;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  web