AOP(Aspect Oriented Programming),即面向切面编程,它利用一种称为"横切"的技术,把软件系统分为两个部分:核心关注点和横切关注点,用来实现诸如权限认证、日志、事务等功能。简单讲就是在指定类的指定方法先后增长通用代码,减小冗余加强功能。java
手动实现:spring
被代理的目标接口编程
package com.xxx.service; public interface RunningService { public void running(); }
被代理的目标实现类app
package com.xxx.service.impl; import org.springframework.stereotype.Component; import com.xxx.service.RunningService; @Component public class RunningServiceImpl implements RunningService { @Override public void running() { System.out.println("do something"); } }
须要增长的通用操做类ide
package com.xxx.proxy; import org.springframework.stereotype.Component; @Component public class Aop { public void before(){ System.out.println("before!"); } public void after(){ System.out.println("after!"); } }
代理工厂类测试
package com.xxx.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyFactory { public static Object newProxyInstance(final Object target,final Aop aop){ ClassLoader classLoader = target.getClass().getClassLoader(); Class<?>[] interfaces = target.getClass().getInterfaces(); InvocationHandler invocationHandler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { aop.before(); Object result = method.invoke(target, args); aop.after(); return result; } }; return Proxy.newProxyInstance(classLoader, interfaces, invocationHandler); } }
spring配置文件spa
<?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.xsd" default-autowire="byType"> <!-- 开启注解扫描 --> <context:component-scan base-package="com.xxx.proxy"></context:component-scan> <!-- 调用工厂方法,返回runningService的代理对象 --> <bean id="runningService_proxy" class="com.xxx.proxy.ProxyFactory" factory-method="newProxyInstance"> <constructor-arg index="0" type="java.lang.Object" ref="runningServiceImpl"></constructor-arg> <constructor-arg index="1" type="com.xxx.proxy.Aop" ref="aop"></constructor-arg> </bean> </beans>
测试类代理
package com.xxx.proxy; import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.xxx.proxy.service.RunningService; public class TestAop { @Test public void test(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); RunningService run = (RunningService)context.getBean("runningService_proxy"); run.running(); } }
运行结果日志