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(); } }
運行結果日誌