aop介绍
AOP(Aspect Oriented Programming),即面向切面编程,能够说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。
面向切面是面向对象中的一种方式而已。在代码执行过程当中,动态嵌入其余代码,叫作面向切面编程。常见的使用场景:
i :日志
ii: 事务
iii:数据库操做
spring
aop的实现方式(schema)
前置通知(MethodBeforeAdvice)数据库
@Component public class MyBeforeAdvice implements MethodBeforeAdvice{ @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("前置通知执行:"+method.getName()); } }
后置通知(AfterReturningAdvice)express
@Component public class AfterAdvice implements AfterReturningAdvice{ @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("后置通知 :"+returnValue); }
环绕通知(MethodInterceptor)编程
@Component public class AroundInterceptor implements MethodInterceptor{ @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("环绕通知执行1"); String msg = (String)invocation.proceed(); System.out.println("环绕通知执行2"); return msg==null?null:msg.toUpperCase(); } }
异常处理通知(ThrowsAdvice)app
@Component public class MyThrowsAdvice implements ThrowsAdvice { public void afterThrowing(Exception ex){ System.out.println("异常参数了:"+ex.getMessage()); } }
测试类框架
public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); IWindow window = ac.getBean("mytarget",IWindow.class); window.say(); System.out.println("----------"); System.out.println(window.doSome()); } }
applicationContext.xml配置文件 ide
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- 开启扫描 --> <context:component-scan base-package="com.sxt.*"></context:component-scan> <!-- 1.注册目标对象 --> <!-- <bean class="com.sxt.pojo.Window" id="window"/> 2.注册前置通知对象--> <bean class="com.sxt.advice.MyBeforeAdvice" id="methodBeforeAdvice"/> <bean class="com.sxt.advice.AfterAdvice" id="afterAdvice"></bean> <bean class="com.sxt.advice.AroundInterceptor" id="around"></bean> <bean class="com.sxt.advice.MyThrowsAdvice" id="myThrowsAdvice"></bean> <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="mytarget"> <property name="target" ref="window" /> <property name="interfaces" value="com.sxt.pojo.IWindow" /> <property name="interceptorNames"> <array> <!-- 关联前置通知 --> <value>methodBeforeAdvice</value> <value>afterAdvice</value> <value>aroundInterceptor</value> <value>myThrowsAdvice</value> </array> </property> </bean> </beans>
基于aspectJ方式实现
对于AOP这种编程思想,不少框架都进行了实现。Spring就是其中之一,能够完成面向切面编程。然而,AspectJ也实现了AOP的功能,且其实现方式更为简捷,使用更为方便,并且还支持注解式开发。因此,Spring又将AspectJ的对于AOP的实现也引入到了本身的框架中。在Spring中使用AOP开发时,通常使用AspectJ的实现方式
测试
xml配置的方式spa
实体类3d
public class Window implements IWindow{ @Override public void say(){ System.out.println("div dir"); } @Override public String doSome(){ System.out.println("你好"); return "hello"; } }
切面类
public class Advice{ public void before(){ System.out.println("前置通知"); } public void afterReturning(){ System.out.println("后置通知"); } public Object around(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("环绕通知1"); Object msg = pjp.proceed(); if (msg != null) { msg = msg.toString().toUpperCase(); System.out.println("环绕通知2"); return msg; } return null; } public void throwing(Exception ex){ System.out.println("参数异常了:"+ex.getMessage()); } public void after(){ System.out.println("最终通知"); } }
测试类
public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); IWindow window = ac.getBean(IWindow.class); window.say(); System.out.println("----------"); System.out.println(window.doSome()); } }
xml配置文件
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 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/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- 注册目标对象 --> <bean class="com.sxt.pojo.Window" id="window"></bean> <!-- 注册切面对象 --> <bean class="com.sxt.advice.Advice" id="myAdvice"></bean> <!-- 3.配置AOP --> <aop:config> <!-- 配置切面对象 --> <aop:aspect ref="myAdvice"> <!-- 配置切面点 --> <aop:pointcut expression="execution(* com.sxt.pojo.*.*(..))" id="pointcut"/> <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/> <aop:before method="before" pointcut-ref="pointcut"/> <aop:around method="around" pointcut-ref="pointcut"/> <aop:after-throwing method="throwing" pointcut-ref="pointcut" throwing="ex"/> <aop:after method="after" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans>
注解的方式
切面类
@Component @Aspect public class Advice{ @Before(value="execution(* com.sxt.*.*.*(..))") public void before(){ System.out.println("前置通知"); } @AfterReturning(value="execution(* com.sxt.*.*.*(..))") public void afterReturning(){ System.out.println("后置通知"); } @Around(value="execution(* com.sxt.pojo.*.*(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("环绕通知1"); Object msg = pjp.proceed(); if (msg != null) { msg = msg.toString().toUpperCase(); System.out.println("环绕通知2"); return msg; } return null; } @AfterThrowing(value="execution(* com.sxt.pojo.*.*(..))",throwing="ex") public void throwing(Exception ex){ System.out.println("参数异常了:"+ex.getMessage()); } @After(value="execution(* com.sxt.pojo.*.*(..))") public void after(){ System.out.println("最终通知"); } }
xml配置文件
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 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/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- 开启扫描 --> <context:component-scan base-package="com.sxt.*"></context:component-scan> <!-- 开启aspectJ注解 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
控制台输入