Spring AOP笔记

首先,web.xml配置一个listener

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


其实,使用默认的springListener配置文件路径:WEB-INF/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<aop:aspectj-autoproxy/>
<bean id="logAspect" class="com.amhuman.comm.LogAspect"></bean>
<bean id="userService" class="com.amhuman.service.UserServiceImpl" />
<bean class="com.amhuman.comm.SpringHelper"></bean>
</beans>


接下来就是编写切面了(这里还用到了自定义的注解,下面会补上代码)

package com.amhuman.comm;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;

@Aspect
public class LogAspect {

@After("execution(public * *(..))")
public void afterSayHello(){
System.out.println("After : ");
}

@Before("execution(public * *(..))")
public void beforeSayHello(){
System.out.println("Before : ");
}

@Around("execution(public * *(..)) && @annotation(com.amhuman.comm.Log)")
public Object doLog(ProceedingJoinPoint pjp) throws Throwable{
String param = "";
Log logAnno = getAnno(pjp);
if(logAnno.id() != -1){
Object obj = pjp.getArgs()[logAnno.id()];
if(logAnno.fieldName() == ""){
param = obj.toString();
}else{
String fieldName = logAnno.fieldName();
Method getMethod = obj.getClass().getMethod("getUserName", null);
System.out.println(obj.getClass().toString());
System.out.println(getMethod.toString());
Object objddd = getMethod.invoke(obj, null);
System.out.println(objddd);
// param = getMethod.invoke(obj, null).toString();
}
}
System.out.println("#before asp : "+ param);
Object ret = pjp.proceed();
System.out.println("#aftor asp");
return ret;
}

private Log getAnno(ProceedingJoinPoint pjp) throws SecurityException, NoSuchMethodException{
Class<?> currClass = pjp.getTarget().getClass();
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
String shortMethodName = method.getName();
Method realMethod = currClass.getMethod(shortMethodName, method.getParameterTypes());
Log logAnnotation = realMethod.getAnnotation(Log.class);
return logAnnotation;
}
}


注解的代码:

package com.amhuman.comm;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface Log {
public int id() default -1;
public String fieldName() default "";
}


写个单元测试跑下:

package com.amhuman.test;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.amhuman.entity.User;
import com.amhuman.service.IUserService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext-test.xml" })
public class SpringTest {

@Resource
IUserService userService;

public IUserService getUserService() {
return userService;
}

public void setUserService(IUserService userService) {
this.userService = userService;
}

@Test
public void testUser(){
System.out.println(userService.getDefaultUser().getUserName());
System.out.println("================================");
System.out.println(userService.findById(100).getUserName());
System.out.println("================================");
System.out.println(userService.find(new User()).getUserName());
}

}


对应的service代码

package com.amhuman.service;

import org.springframework.util.StringUtils;

import com.amhuman.comm.Log;
import com.amhuman.entity.User;

public class UserServiceImpl implements IUserService {
private String userName;

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

/* (non-Javadoc)
* @see com.amhuman.service.IUserService#getDefaultUser()
*/
@Override
public User getDefaultUser(){
System.out.println("###");
User user = new User();
user.setUserId(1001);
if(StringUtils.hasLength(this.userName)){
user.setUserName(this.userName);
}else{
user.setUserName("WUYC-TEST");
}
return user;
}

@Override
@Log(id = 0,fieldName="userId")
public User find(User user) {
if(user == null){
return getDefaultUser();
}
user.setUserName("WUTIANYU");
return user;
}

@Override
@Log(id = 0)
public User findById(Integer id) {
if(id == null){
return getDefaultUser();
}
User user = new User();
user.setUserId(id);
user.setUserName("UserName["+id+"]");
return user;
}
}



搞定!
好的,关于Spring AOP笔记和源码讲解,我可以给你简单介绍一下。 Spring AOPSpring框架中的一个重要模块,提供了基于代理的AOP实现。AOP(Aspect Oriented Programming)面向切面编程,是一种编程思想,它通过将横切关注点与业务逻辑分离,使得系统的关注点更加清晰,代码更加简洁易懂,同时也提高了代码的可维护性和可扩展性。 在Spring AOP中,切面(Aspect)是一个类,它包含了通知(Advice)和切点(Pointcut)。通知是在切点上执行的操作,例如在方法执行前或执行后执行一些额外的逻辑。而切点则是一个表达式,用于匹配目标对象中的方法,从而确定哪些方法会被通知所影响。 Spring AOP提供了四种通知类型,分别是: 1. 前置通知(Before advice):在目标方法执行之前执行。 2. 后置通知(After returning advice):在目标方法执行之后执行,在目标方法没有抛出异常的情况下。 3. 异常通知(After throwing advice):在目标方法抛出异常后执行。 4. 最终通知(After advice):无论目标方法是否抛出异常,最终通知都会执行。 除了通知之外,Spring AOP还提供了环绕通知(Around advice),它可以在目标方法执行前和执行后执行一些额外的逻辑,并且可以控制目标方法的执行。 在Spring AOP中,代理是通过JDK动态代理或者CGLIB字节码生成技术生成的。如果目标对象实现了接口,则使用JDK动态代理实现代理;如果目标对象没有实现接口,则使用CGLIB字节码生成技术实现代理。 在Spring AOP中,通知和切点都可以使用注解的方式来声明。例如,使用@Aspect注解声明一个切面类,使用@Before、@After、@AfterReturning、@AfterThrowing和@Around注解声明通知方法,使用@Pointcut注解声明切点表达式。 关于Spring AOP源码讲解,它的实现主要涉及到以下几个类: 1. AdvisedSupport类:封装了目标对象、切面和通知等信息。 2. ProxyFactory类:用于生成代理对象的工厂类。 3. AopProxy接口:代理对象的接口。 4. JdkDynamicAopProxy和CglibAopProxy类:实现了AopProxy接口,分别用于基于JDK动态代理和CGLIB字节码生成技术的代理对象。 以上是Spring AOP笔记和简单源码讲解,希望能对你有所帮助。如果有什么不清楚的地方,可以继续问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值