AOP术语都非常抽象,结合某些小例子就会形象、具体一些。
连接点(Joinpoint)
Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时及方法调用前后,这些程序执行点织入增强。
黑客攻击系统需要找到突破口,从某种程度上来说,AOP也可以看成一个黑客(因为它要向目标类中嵌入额外的代码逻辑),而连接点就是AOP向目标类打入楔子的候选锚点。
接口名:org.aspectj.lang.JoinPoint
其中,最常用的是以下几个:
- getArgs()
- getTarget()
- getSignature()
相关接口:org.aspectj.lang.ProceedingJoinPoint extends JoinPoint
其中,最常用的是以下几个:
- proceed()
- proceed(Object[])
小例子(环绕增强)
public class UserInfo {
private String name;
public UserInfo(String name) {
this.name = name;
}
...
}
public interface IBaseMapper {
void insert(UserInfo userInfo);
}
public interface IOrderMapper extends IBaseMapper {
void save(String name, Integer age);
}
@Service
public class OrderMapperService implements IOrderMapper {
@Override
public void save(String name, Integer age) {
System.out.println("### 进入save(..),name=" + name);
}
@Override
public void insert(UserInfo userInfo) {
System.out.println("### 进入insert(..)");
}
}
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
@Aspect
@Component
public class OrderAspect {
// 也可以先自定义注解,再:@Pointcut("@annotation(com.xxx.MyAnnotation)")
@Pointcut(value = "execution(* com.javatpoint.service.IOrderMapper.*(..))")
private void logDisplayingBalance() {
}
@Around(value = "logDisplayingBalance()")
public void aroundAdvice(ProceedingJoinPoint jp) throws Throwable {
System.out.println("### The method aroundAdvice() before invokation of the method " + jp.getSignature().getName() + " method");
try {
jp.proceed();
} finally {
}
// ProceedingJoinPoint的常用方法
Object[] args = jp.getArgs();
MethodSignature methodSignature = (MethodSignature)jp.getSignature();
Method method = methodSignature.getMethod();
Class<?>[] parameterTypes = method.getParameterTypes();
Object target = jp.getTarget();
// 模拟:修改为大写后,再次重复执行
repeatExecuteMethod(target, method, args);
System.out.println("### The method aroundAdvice() after invokation of the method " + jp.getSignature().getName() + " method");
}
/**
* 重复执行
* 可以加入一些特殊处理,例如:小写转大写、加密、脱敏处理等
* @param target
* @param method
* @param args
* @return
*/
public Object repeatExecuteMethod(Object target, Method method, Object[] args) {
try {
Object invoke = method.invoke(target, toUpperCase(args));
return invoke;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object[] toUpperCase(Object[] args) {
if (args == null || args.length == 0) {
return args;
}
List<Object> list = new ArrayList<>();
for (Object obj : args) {
if (obj instanceof String) {
String obj2Str = (String)obj;
list.add(obj2Str.toUpperCase());
} else {
list.add(obj);
}
}
return list.toArray();
}
}
import com.javatpoint.service.IOrderMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.javatpoint.service.BankService;
@SpringBootApplication
// @EnableAspectJAutoProxy annotation enables support for handling the components marked with @Aspect annotation.
// It is similar to tag in the xml configuration.
@EnableAspectJAutoProxy
public class AopAroundAdviceExampleApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(AopAroundAdviceExampleApplication.class, args);
IOrderMapper order = context.getBean(IOrderMapper.class);
order.save("yaoyao", 12);
order.insert(new UserInfo("jjk"));
context.close();
}
}
前置增强
@Aspect
@Component
public class EmployeeServiceAspect {
@Before(value = "execution(* com.javatpoint.service.EmployeeService.*(..)) and args(empId2, fname, sname)")
public void beforeAdvice(JoinPoint joinPoint, String empId2, String fname, String sname) {
System.out.println("Before method:" + joinPoint.getSignature());
System.out.println("Creating Employee with first name - " + fname + ", second name - " + sname + " and id - " + empId2);
}
}
注意上面“ and args ”的用法,不是EmployeeService类的所有方法都增强,仅仅是三个参数,且三个String类型的方法才增强。
后置增强
@Aspect
@Component
public class EmployeeServiceAspect {
@After(value = "execution(* com.javatpoint.service.EmployeeService.*(..)) and args(empId, fname, sname)")
public void afterAdvice(JoinPoint joinPoint, String empId, String fname, String sname) {
System.out.println("After method:" + joinPoint.getSignature());
System.out.println("Successfully created Employee with first name - " + fname + ", second name - " + sname + " and id - " + empId);
}
}
方法返回值前增强
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import com.javatpoint.model.Account;
@Aspect
@Component
public class AccountAspect {
//implementing after returning advice
@AfterReturning(value = "execution(* com.javatpoint.service.impl.AccountServiceImpl.*(..))", returning = "account")
public void afterReturningAdvice(JoinPoint joinPoint, Account account) {
System.out.println("After Returing method:" + joinPoint.getSignature());
System.out.println(account);
}
抛出异常增强
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class AccountAspect {
//implementing after throwing advice
@AfterThrowing(value = "execution(* com.javatpoint.service.impl.AccountServiceImpl.*(..))", throwing = "ex")
public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) {
System.out.println("After Throwing exception in method:" + joinPoint.getSignature());
System.out.println("Exception is:" + ex.getMessage());
}
}
资料
- https://www.javatpoint.com/spring-boot-aop
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/17221.html