重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
演示5种方式配置文件AOP
创新互联是一家专注于网站建设、成都网站建设与策划设计,图们网站建设哪家好?创新互联做网站,专注于网站建设10多年,网设计领域的专业建站公司;建站业务涵盖:图们等地区。图们做网站价格咨询:13518219792
1. bean class="cn.hncu.spring4x.aop.Cat" id="cat"/bean
!-- 切点 --
bean class="org.springframework.aop.support.JdkRegexpMethodPointcut" id="pointcut"
property name="pattern" value=".*run.*"/property
/bean
!-- 通知 ,要自己写--
bean class="cn.hncu.spring4x.aop.AroundAdvice" id="advice"/bean
!-- 切面=切点+通知 --
bean class="org.springframework.aop.support.DefaultPointcutAdvisor" id="advisor"
property name="advice" ref="advice"/property
property name="pointcut" ref="pointcut"/property
/bean
bean class="org.springframework.aop.framework.ProxyFactoryBean" id="catProxide"
property name="target" ref="cat"/property
property name="interceptorNames"
list
valueadvisor/value
/list
/property
/bean
2. bean class="cn.hncu.spring4x.aop.Cat" id="cat"/bean
!-- 切面=切点+通知 (把切点和通知写成内部bean)--
bean class="org.springframework.aop.support.DefaultPointcutAdvisor" id="advisor"
property name="advice"
bean class="cn.hncu.spring4x.aop.AroundAdvice"/bean
/property
property name="pointcut"
bean class="org.springframework.aop.support.JdkRegexpMethodPointcut"
property name="patterns"
list
value.*run.*/value
value.*say.*/value
/list
/property
/bean
/property
/bean
bean class="org.springframework.aop.framework.ProxyFactoryBean" id="catProxide"
property name="target" ref="cat"/property
property name="interceptorNames"
list
valueadvisor/value
/list
/property
/bean
3.bean class="cn.hncu.spring4x.aop.Cat" id="cat"/bean
!--//直接在切面bean中配置“切点的正则表达式”,省去“切点bean”的配置 用到这个类 org.springframework.aop.support.RegexpMethodPointcutAdvisor --
bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="advisor"
property name="advice"
bean class="cn.hncu.spring4x.aop.AroundAdvice"/bean
/property
property name="patterns"
list
value.*run.*/value
/list
/property
/bean
bean class="org.springframework.aop.framework.ProxyFactoryBean" id="catProxide"
property name="target" ref="cat"/property
property name="interceptorNames"
list
valueadvisor/value
/list
/property
/bean
4. bean class="cn.hncu.spring4x.aop.Cat" id="cat"/bean
!--//直接在切面bean中配置“切点的正则表达式”,省去“切点bean”的配置 用到这个类 org.springframework.aop.support.RegexpMethodPointcutAdvisor --
bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="advisor"
property name="advice"
bean class="cn.hncu.spring4x.aop.AroundAdvice"/bean
/property
property name="patterns"
list
value.*run.*/value
/list
/property
/bean
!-- 自动代理 --
bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/bean
5. bean class="cn.hncu.spring4x.aop.Cat" id="cat"/bean
!--//直接在切面bean中配置“切点的正则表达式”,省去“切点bean”的配置 用到这个类 org.springframework.aop.support.RegexpMethodPointcutAdvisor --
bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="advisor"
property name="advice"
bean class="cn.hncu.spring4x.aop.AroundAdvice"/bean
/property
property name="patterns"
list
value.*run.*/value
/list
/property
/bean
!-- 自动代理 --
bean class="cn.hncu.spring4x.aop.MyAutoProxy"/bean
面向切面编程(AOP),就是关注程序运行的过程,切面就是要把方法切开,分别执行前,执行中,执行后(可能更细化)等多个步骤,分别针对这三个阶段进行处理。以获得逻辑过程中各部分之间低耦合性的隔离效果。
具体使用场景:
事务管理:我们在操作数据库的时候需要在操作前打开事务,结束后提交事务(或回滚事务),按往常的编码方式,我们会在每个方法前、后都添加一些事务操作的重复的代码,使得每个类都与事务操作相耦合;而使用了AOP,代码上看上去就是直接操作的数据库,而我们通过某种机制,可让代码在你不察觉的情况下进行了事务开启和提交(或回滚),事实上Spring就提供了这种事务机制。
差不多的场景还有日志的记录
1.首先创建一个自定义注解拦截Controller类,代码如下
/**
* 自定义注解 拦截Controller
*/
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ControllerLog {
String desc() default "";//标示默认打印空
}
2.创建一个打印日志的切面类,引入切面注解@Aspect,
新建方法代码如下:
// Controller层切点
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
public void recordLog() {
}
@Around("recordLog()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
// ExPatternParser.initLogger();
long start = System.currentTimeMillis();
Object[] args = pjp.getArgs();
String remark = this.getControllerMethodDescription(pjp);
Object retVal = null;
try {
retVal = pjp.proceed();
} catch (Throwable e) {
// TODO Auto-generated catch block
logger.error("请求失败" + e.toString(),e);
remark = remark + "。Exception Cause By " + e.toString();
throw e;
}finally{
long end = System.currentTimeMillis();
long cost = end - start;
//打印访问日志
// Controller中所有方法的参数,前两个分别为:Request,Response
if(args != null args.length 0){
Object o = args[0];
if(o instanceof HttpServletRequest){
HttpServletRequest request = (HttpServletRequest) args[0];
PrintLog.visit(request, cost,remark);
}
}
}
return retVal;
}
/**
* 获取注解中对方法的描述信息 用于Controller层注解
* @param joinPoint切点
* @return 方法描述
* @throws Exception
*/
public static String getControllerMethodDescription(ProceedingJoinPoint joinPoint)
throws Exception {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String description = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
ControllerLog controllerLog = method.getAnnotation(ControllerLog.class);
if(controllerLog !=null){
description =
controllerLog.desc();
}
break;
}
}
}
return description;
}
3.然后在每个Controller类上加上注解:
@ControllerLog(desc = "要 打印的日志内容")
aop的事务代理机制最重要的放心是确定切入点,面,通知.具体看代码,下面是在spring中配置的我自己写的一个异常处理的aop作用类 ,该配置切入面在于在controller包下的所有类的所有注解为aspect的切面类,通知类型为表示在目标方法之前切入,切入点为controller包下的所有类所有方法.至于楼主所说的静态方法对于事务机制应该没什么区别吧,只要用within方法一样可以的
!-- 定义共同处理组件 --
bean id="loggerBean"
class="org.tedu.cloudnote.aspect.LoggerBean"
/bean
!-- 将loggerBean组件切入到Controller方法上 --
aop:config
!-- 要切入哪个共同处理组件,ref指定共同组件id值 --
aop:aspect ref="loggerBean"
!-- aop:before表示在目标方法之前切入,
method指定方法名;pointcut指定目标组件 --
aop:before method="logController"
pointcut="within(org.tedu.cloudnote.controller..*)"/
/aop:aspect
/aop:config
之后这个bean所定义的 自定义类的代码如下 ,希望楼主给个采纳,如果问友喜欢,也可以给我个赞哦,摸摸大
package org.tedu.cloudnote.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
//封装共同处理的组件
@Component//扫描,等价于bean定义
@Aspect//等价于aop:aspect ref=""
public class LoggerBean {
//要在Controller.execute开始位置切入
//方法规则:public void 方法名(){...} (前置通知)
@Before("within(org.tedu.cloudnote.controller..*)")
//等价于aop:before method="logController" pointcut=""
public void logController(){
System.out.println("进入Controller组件处理");
}
}