SpringAOP在项目中的简单应用(三)

2014-11-23 23:37:56 · 作者: · 浏览: 3
出一些常见切入点表达式的例子。

任意公共方法的执行:

execution(public **(..))任何一个以“set”开始的方法的执行:

execution(*set*(..))AccountService 接口的任意方法的执行:

execution(*com.xyz.service.AccountService.*(..))定义在service包里的任意方法的执行:

execution(*com.xyz.service.*.*(..))定义在service包或者子包里的任意方法的执行:

execution(*com.xyz.service..*.*(..))在service包里的任意连接点(在Spring AOP中只是方法执行):

within(com.xyz.service.*)在service包或者子包里的任意连接点(在Spring AOP中只是方法执行):

within(com.xyz.service..*)实现了AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执行):

this(com.xyz.service.AccountService)'this'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知体内访问到的部分。

实现了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行):

target(com.xyz.service.AccountService)'target'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得目标对象可以在通知体内访问到的部分。

任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点(在Spring AOP中只是方法执行)

args(java.io.Serializable)'args'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知体内访问到的部分。

请注意在例子中给出的切入点不同于execution(* *(java.io.Serializable)): args只有在动态运行时候传入参数是可序列化的(Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。

有一个 @Transactional 注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)

@target(org.springframework.transaction.annotation.Transactional)'@target'也可以在binding form中使用:请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。

任何一个目标对象声明的类型有一个@Transactional 注解的连接点(在Spring AOP中只是方法执行)

@within(org.springframework.transaction.annotation.Transactional)'@within'也可以在bindingform中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。

任何一个执行的方法有一个@Transactional annotation的连接点(在Spring AOP中只是方法执行)

@annotation(org.springframework.transaction.annotation.Transactional)'@annotation'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。

任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点(在Spring AOP中只是方法执行)

@args(com.xyz.security.Classified)'@args'也可以在bindingform中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。

还有这里我主要用了@Around的注解,其实还有好几种方式,它们的作用各不相同:

@Before:前置通知,在切点方法集合执行前,执行前置通知;

@After:后置通知,在切点方法集合执行后,执行后置通知;

@AfterReturning:后置通知,在切点方法集合执行后返回结果后,执行后置通知;

@Around :环绕通知(##环绕通知的方法中一定要有ProceedingJoinPoint参数,与Filter中的doFilter方法类似)

@AfterThrowing :异常通知,切点方法集合执行抛异常后执行处理;

具体实例可以看:http://blog.sina.com.cn/s/blog_7ffb8dd501014am6. html

在这里遇到一个问题:因为原方法是:public ModelAndView dayiLoginInit(HttpServletRequest request)只有一个参数,所以 上面的语句:
HttpServletResponse response = (HttpServletResponse) pjp.getArgs()[1];
是报数据越界的异常的,因为有些模是需要用到response 参数的,为了解决这个问题,我在网上找了解决方案,即配置过滤器,并运用线程变量ThreadLocal来实现: 过滤器:
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @Description: 云平台割接过滤器
* @author 柯颖波
* @date 2014-4-1 下午03:04:34 
* @version v1.0
 */
public class GetContextFilter implements Filter {

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		SysContext.setRequest((Ht