AOP使用总结

1. AOP简介

AOP是一种编程范式,它主要是为了将非功能模块与业务模块分离开来,让我们更好的管理这些非功能模块。

它的使用场景有:权限控制、日志打印、事务控制、缓存控制、异常处理

2. AOP使用

  1. 在类上注解 @Aspect
  2. 如果想在方法执行前做操作,那么注解@Before注解
  3. 如果想在方法执行后做操作,那么注解@After注解

五大Advice注解:

  • @Before 方法执行前执行该切面方法
  • @After 方法执行后执行该切面方法
  • @AfterThrowing 方法抛出异常后执行该切面方法
  • @AfterReturning 方法返回值后执行该切面方法
  • @Around 环绕注解,集合前面四大注解

2.1 @Aspect

注解在类上,表明此类是一个面向切面的类,同时也要记得在类上注解@Component或者@Service 将此类交给Spring管理

2.2 @Poincut

用来注解在方法上,表明此方法为切面方法

常用表达式有:

@Poincut("@annotation(myLogger)") //只拦截有注解为@myLogger的方法

@Poincut("within(com.pibigstar.service.*) ") //只拦截com.pibigstar.service包下的方法

//拦截public修饰符,返回值为任意类型,com.pibigstar.servce包下以Service结尾的类的所有方法,方法参数为任意
@Poincut("execution("public * com.pibigstar.service.*Service.*(..)") 

@Poincut("bean(*service)") //只拦截所有bean中已service结尾的bean中的方法

Poincut表达式

designators(指示器)常用的表达式

2.3 @Before

在方法执行下执行该切面方法,其用法与@Poincut类似

//只拦截com.pibigstar包下,并且注解为myLogger的方法
@Before("within(com.pibigstar..*) && @annotation(myLogger)")
public void printBeforeLog(MyLogger myLogger) {
    String host = IPUtil.getIPAddr(request);
    log.info("====IP:"+host+":开始执行:"+myLogger.description()+"=======");
}

2.4 @After

在方法执行后执行该切面方法

//方法结束后
@After("within(com.pibigstar..*) && @annotation(myLogger)")
public void printAfterLog(MyLogger myLogger) {
    log.info("=====结束执行:"+myLogger.description()+"=====");
}

2.5 @AfterThrowing

当方法抛出异常后执行该切面方法

@AfterThrowing(@annotation(myLogger)",throwing = "e")
public void printExceptionLog(MyLogger myLogger,Exception e) {
    log.info("======执行:"+myLogger.description()+"异常:"+ e +"=====");
}

2.6 @AfterReturning

方法有返回值,打印出方法的返回值

//方法有返回值
@AfterReturning(value = "@annotation(myLogger)",returning="result")
public void printReturn(Object result) {
    log.info("======方法的返回值:"+result+"========");
}

2.7 @Around

集合@Before,@After,@AfterReturning,@AfterThrowing 四大注解

//集合前面四大注解
    @Around("@annotation(myLogger)")
    public Object printAround(ProceedingJoinPoint joinPoint,MyLogger myLogger) {
        Object result = null;
        try {
            log.info("======开始执行:"+myLogger.description()+"=======");
            result = joinPoint.proceed(joinPoint.getArgs());
            log.info("======方法的返回值:"+result+"========");
        } catch (Throwable e) {
            e.printStackTrace();
            log.info("======执行异常"+ e +"=======");
        }finally {
            log.info("======结束执行:"+myLogger.description()+"=======");
        }
        return result;
    }
### 面向切面编程(AOP)的实现方式 #### 动态代理机制 Java 中的 AOP 主要依赖于动态代理机制来实现。动态代理允许在运行时创建代理对象并拦截方法调用,从而可以在不修改原有代码的基础上添加额外的功能[^4]。 以下是基于接口的动态代理的一个简单示例: ```java import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxyExample { public static void main(String[] args) { MyInterface myInterface = new MyClass(); MyInterface proxyInstance = (MyInterface) Proxy.newProxyInstance( myInterface.getClass().getClassLoader(), myInterface.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before method call"); Object result = method.invoke(myInterface, args); System.out.println("After method call"); return result; } }); proxyInstance.doSomething(); } interface MyInterface { void doSomething(); } static class MyClass implements MyInterface { @Override public void doSomething() { System.out.println("Doing something..."); } } } ``` 上述代码展示了如何通过 `InvocationHandler` 来拦截方法调用,并在方法执行前后加入自定义逻辑。 --- #### 切面的应用场景 AOP 的核心在于将横切关注点从业务逻辑中分离出来。常见的应用场景包括但不限于事务管理、日志记录、权限校验以及性能监控等[^1]。例如,在 Spring 框架中,可以通过声明式的注解轻松实现这些功能[^3]。 下面是一个简单的日志记录切面示例: ```java import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logMethodCall() { System.out.println("Logging the method call."); } } ``` 在这个例子中,`@Before` 注解指定了切入点表达式,表示在指定包下的所有方法执行前都会触发该切面的方法[^2]。 --- #### 声明式事务管理 除了日志记录外,AOP 还常用于简化事务管理。Spring 提供了强大的支持,使得开发者无需手动编写复杂的事务控制代码。以下是如何配置事务管理器的例子: ```xml <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="find*" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* com.example.service.*.*(..))" id="serviceMethods"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods"/> </aop:config> ``` 以上 XML 配置文件说明了如何利用 AOP 和声明式事务管理相结合的方式减少重复代码量。 --- #### 总结 AOP 是一种增强软件模块化的技术手段,它能够帮助程序员更好地应对复杂的企业级需求。无论是通过动态代理还是静态织入,AOP 都提供了灵活的方式来解决那些难以封装到单一类中的通用问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值