springmvc 在controller层使用aop切面编程

支持作者

最便宜的卫生纸

第一 编写切点

 

首先我们在Springmvc的controller层中定义一个测试用的切点

 

 

package com.lin.controller;


import java.util.HashMap;
import java.util.Map;

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.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

@RequestMapping("/sys/login")
@Controller
public class LoginController {

	@RequestMapping(value="/t")
	@ResponseBody
	public Map<String,Object> test(HttpServletRequest request, HttpServletResponse response){
		Map<String,Object> map=new HashMap<String, Object>();
		System.out.println("我是切点");
		return map;
	}
}

 

第二 定义切面

 

 

 

Spring 借助AspectJ的切点表达式语言来定义Spring切面。

下面我们来看一个切点表达式,这个表达式能够设置当test(..)方法执行时触发通知的调用。

我们使用execution()指示器选择LoginController的test()方法。方法表达式以“*”号开始,表明我们不关心方法返回值的类型。然后,我们指定了全限定类名和方法名。对于方法参数列表,我们使用两个点好(..)表明切点要选择任意的 test()方法,无论该方法的参数是什么。

 

编写切面POJO类

 

package com.lin.common.aop;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Component
@Aspect
public class Audience {
   
	@Before("execution(* com.lin.controller.LoginController.test(..))")
	public void before(){
	    RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();  //获取request 可以从中获取参数或cookie
		System.out.println("我是切面");
	}	
}

@Component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>)

 

Audience类使用@Aspect注解进行了标注。该注解表明Audience不仅仅是一个POJO,还是一个切面。Audience类中的方法都使用注解来定义切面的具体行为。

 

Spring使用AspectJ注解来声明通知方法

@Before  通知方法还会在目标方法调用之前执行

@Around 通知方法会将目标方法封装起来

@AfterThrowing 通知方法会在目标方法抛出异常后调用

@AfterReturning 通知方法会在目标方法返回后调用

@After 通知方法会在目标方法返回或抛出异常后调用

 

第三 在XML中,通过Spring的aop命名空间启用AspectJ代理

在Springmvc中使用AOP我们需要将启用代理放在Spring-mvc.xml中,否则代理不生效。

 

原因(摘自其他博客,该部分内容原地址:http://blog.csdn.net/my_nice_life/article/details/52910718):

(部分借鉴)CGLIB代理配置在了applicationContext.xml 核心配置文件中,该配置文件会被ContextLoaderListenerclass加载,Spring会创建一个WebApplicationContext上下文,称为父上下文(父容器) ,保存在ServletContext中,key为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。

而spring-mvc.xml是DispatcherServlet,可以同时配置多个,每个 DispatcherServlet有一个自己的上下文对象(WebApplicationContext),称为子上下文(子容器),子上下文可以访问父上下文中的内容,但父上下文不能访问子上下文中的内容。 它也保存在 ServletContext中,key是”org.springframework.web.servlet.FrameworkServlet.CONTEXT”+Servlet名称

当spring加在父容器的时候就会去找切入点,但是这个时候切入的controller是在子容器中的,父容器是无法访问子容器,所以就拦截不到。如果将上述的配置文件放到spring-mvc.xml中,那么问题就解决了。我已经测试可以通过URL访问触发切点了。

 

配置文件

 

<span style="color:#000000"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:p="http://www.springframework.org/schema/p"  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  <!-- Spring aop 命名空间-->
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="
   http://www.springframework.org/schema/aop 
   http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
       
    <!-- 扫描controller(controller层注入) -->
   <context:component-scan base-package="com.lin.controller"/>
    <!-- 开启spring对注解驱动的支持 -->
    <mvc:annotation-driven/>
   <!-- 启动AspectJ自动代理 --> 
   <aop:aspectj-autoproxy proxy-target-class="true"/>
 </beans></span>

 

测试结果

 


 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值