1. AOP的原理 点击查看
Spring有两大核心,IOC和AOP。IOC在java web项目中无时无刻不在使用。然而AOP用的比较少,的确也是一般的项目用的场所不多。事务控制基本都用,但却是Spring封装的不需要我们再去实现,但Spring的AOP远 不止这些,不能因为项目中没有使用,而不去学习及理解。我觉得这是作为一个java web软件开发人员必须具备的技能。业内很多将AOP应用在日志记录上,可惜我们项目没这么做,后面需要学习下。在这先把Spring AOP的基本用法,在脑子里理一边,做一次积累。
2、概念术语
在开始之前,需要理解Spring aop 的一些基本的概念术语(总结的个人理解,并非Spring官方定义):
切面(aspect):用来切插业务方法的类。
连接点(joinpoint):是切面类和业务类的连接点,其实就是封装了业务方法的一些基本属性,作为通知的参数来解析。
通知(advice):在切面类中,声明对业务方法做额外处理的方法。
切入点(pointcut):业务类中指定的方法,作为切面切入的点。其实就是指定某个方法作为切面切的地方。
目标对象(target object):被代理对象。
AOP代理(aop proxy):代理对象。
通知:
前置通知(before advice):在切入点之前执行。
后置通知(after returning advice):在切入点执行完成后,执行通知。
环绕通知(around advice):包围切入点,调用方法前后完成自定义行为。
异常通知(after throwing advice):在切入点抛出异常后,执行通知。
3、Spring AOP环境
要在项目中使用Spring AOP 则需要在项目中导入除了spring jar包之外,还有aspectjweaver.jar,aopalliance.jar ,asm.jar 和cglib.jar 。
好了,前提工作准备完成,Spring 提供了很多的实现AOP的方式,在学习过程中,循序渐进。进行Spring 接口方式,schema配置方式和注解的三种方式进行学习。好了废话不多说了,开始spring aop学习之旅:
4、方式一:AOP接口
利用Spring AOP接口实现AOP,主要是为了指定自定义通知来供spring AOP机制识别。主要接口:前置通知 MethodBeforeAdvice ,后置通知:AfterReturningAdvice,环绕通知:MethodInterceptor,异常通知: ThrowsAdvice 。见例子代码:
package cn.sxt.log; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class AfterLog implements AfterReturningAdvice{ /** * 目标方法执行后执行的通知 * returnValue--返回值 * method 被调用的方法对象 * args 被调用的方法对象的参数 * target 被调用的方法对象的目标对象 * */ @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"被成功执行,返回值是:"+returnValue); } }
AfterLog
package cn.sxt.log; import java.lang.reflect.Method; import org.springframework.aop.ThrowsAdvice; public class ExceptionLog implements ThrowsAdvice { public void afterThrowing(Method method,Exception ex) throws Throwable { } }
ExceptionLog
package cn.sxt.log; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class Log implements MethodBeforeAdvice{ /** * @param method 被调用方法对象 * @param args 被调用的方法的参数 * @param target 被调用的方法的目标对象 * */ @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行"); } }
Log
package cn.sxt.service; public interface UserService { public void add(); public String update(int a); public void delete(); public void search(); }
UserService
package cn.sxt.service.impl; import cn.sxt.service.UserService; public class UserServiceImpl implements UserService { @Override public void add() { System.out.println("增加用户"); } @Override public String update(int a) { System.out.println("修改用户"); return "abc"; } @Override public void delete() { System.out.println("删除用户"); } @Override public void search() { System.out.println("查询用户"); } }
UserServiceImpl
package cn.sxt.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.sxt.service.UserService; public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService)ac.getBean("userService"); userService.update(2); } } /*cn.sxt.service.impl.UserServiceImpl的update方法被执行 修改用户 cn.sxt.service.impl.UserServiceImpl的update被成功执行,返回值是:abc*/
Test
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="cn.sxt.service.impl.UserServiceImpl"/> <bean id="log" class="cn.sxt.log.Log"/> <bean id="afterLog" class="cn.sxt.log.AfterLog"/> <aop:config> <aop:pointcut expression="execution(* cn.sxt.service.impl.*.*(..))" id="pointcut"/> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> </beans>
beans.xml
方式二:AOP接口
package cn.sxt.log; public class Log { public void before(){ System.out.println("-----方法执行前-----"); } public void after(){ System.out.println("-----方法执行后-----"); } }
Log
package cn.sxt.service; public interface UserService { public void add(); public int delete(); }
UserService
package cn.sxt.service.impl; import cn.sxt.service.UserService; public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("-------添加用户数据-------"); } @Override public int delete() { System.out.println("-------删除用户数据-------"); return 1; } }
UserServiceImpl
package cn.sxt.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.sxt.service.UserService; public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService)ac.getBean("userService"); userService.delete(); } } /*-----方法执行前----- -------删除用户数据------- -----方法执行后----- */
Test
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="cn.sxt.service.impl.UserServiceImpl"/> <bean id="log" class="cn.sxt.log.Log"/> <aop:config> <aop:aspect ref="log"> <aop:pointcut expression="execution(* cn.sxt.service.impl.*.*(..))" id="pointcut"/> <aop:before method="before" pointcut-ref="pointcut"/> <aop:after method="after" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans>
beans.xml
方式三:AOP接口 (包名和类位置和二一样)
package cn.sxt.log; 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; @Aspect public class Log { @Before("execution(* cn.sxt.service.impl.*.*(..))") public void before(){ System.out.println("-----方法执行前-----"); } @After("execution(* cn.sxt.service.impl.*.*(..))") public void after(){ System.out.println("-----方法执行后-----"); } @Around("execution(* cn.sxt.service.impl.*.*(..))") public Object aroud(ProceedingJoinPoint jp) throws Throwable{ System.out.println("环绕前"); System.out.println("签名:"+jp.getSignature()); //执行目标方法 Object result = jp.proceed(); System.out.println("环绕后"); return result; } }
Log
package cn.sxt.service; public interface UserService { public void add(); public int delete(); }
UserService
package cn.sxt.service.impl; import cn.sxt.service.UserService; public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("-------添加用户数据-------"); } public int add(int a,int c){ return 1; } @Override public int delete() { System.out.println("-------删除用户数据-------"); return 1; } }
UserServiceImpl
package cn.sxt.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.sxt.service.UserService; public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService)ac.getBean("userService"); userService.delete(); } } /*环绕前 签名:int cn.sxt.service.UserService.delete() -----方法执行前----- -------删除用户数据------- 环绕后 -----方法执行后----- */
Test
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="cn.sxt.service.impl.UserServiceImpl"/> <bean id="log" class="cn.sxt.log.Log"/> <aop:aspectj-autoproxy/> </beans>
beans.xml
原文地址:https://www.cnblogs.com/ou-pc/p/8214846.html