AOP的實現有兩種,一種是接口的實現,一種是產生本身實現,分別的表明爲JDK的Proxy和CGLIB的Proxyhtml
下面是模擬接口代理實現 ,經過模擬JDK的動態代理,更深入的理解java
經過動態代理能夠面向切面編程spring
1 定義被代理的對象和接口apache
- public interface BookInterface {
- void selling();
- }
- public interface PhoneInterface {
- void selling();
- }
- public class Book implements BookInterface {
- @Override
- public void selling() {
- System.out.println("books selling.....");
- }
- }
- public class VivoPhone implements PhoneInterface {
- @Override
- public void selling() {
- System.out.println("selling vivo x5");
- }
- }
2 定義切面類編程
- public class TimeAspect {
- static long bgn;
- public static void before(){
- bgn = System.currentTimeMillis();
- System.out.println("begin time... " + bgn);
- }
- public static void after(){
- long end = System.currentTimeMillis();
- System.out.println("end time... " + (end-bgn));
- }
- }
- public class LogAspect{
- public static void before(){
-
- System.out.println("begin log...");
- }
- public static void after(){
- System.out.println("finish log...");
- }
- }
3 定義InvocationHander 代理接口ide
- import java.lang.reflect.Method;
- public interface InvocationHander {
- public void invoke(Object o,Method m);
- }
代理類(切面編程裏面也能夠作一些特殊的處理)函數
- import java.lang.reflect.Method;
- import jdkproxy.LogTranService;
- import jdkproxy.TimeTranService;
-
- public class ProxyHander implements InvocationHander {
- private Object target;
- public ProxyHander(Object target) {
- this.target = target;
- }
- @Override
- public void invoke(Object o, Method m) {
- try {
- TimeTranService.before();
- if(!(o instanceof BookInterface)){
- LogTranService.before();
- }
-
- m.invoke(target);
-
- if(!(o instanceof BookInterface)){
- LogTranService.after();
- }
- TimeTranService.after();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
動態代理類測試
- import java.io.File;
- import java.io.IOException;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Method;
-
- import javax.tools.JavaCompiler;
- import javax.tools.JavaCompiler.CompilationTask;
- import javax.tools.StandardJavaFileManager;
- import javax.tools.ToolProvider;
-
-
- import org.apache.commons.io.FileUtils;
-
- public class Proxy {
-
- private Proxy(){
- }
-
- public static Object newProxyInstance(Class inter,InvocationHander h){
- String packageName = inter.getPackage().getName();
-
- String proxyClassName = "$"+packageName.replace(".","_") + "_" + inter.getSimpleName() +"Proxy";
-
- String InHanderPackage = h.getClass().getPackage().getName();
- String rt = "\r\n";
- String methodCode = "";
- for (Method method:inter.getMethods()) {
- methodCode+=" @Override"+rt+
-
- " public void "+ method.getName()+"() {"+rt+
- " try{"+rt+
- " Method method = "+inter.getName()+".class.getMethod(\""
- + method.getName()+ "\");"+rt+
- " h.invoke(this,method); "+rt+
- " }catch(Exception e ){" +rt+
- " e.printStackTrace();" +rt+
- " }"+rt+
- " }";
- }
-
- String javaCode=
- "package "+packageName+";"+rt+
- "import "+InHanderPackage+".InvocationHander;"+rt+
-
- "import java.lang.reflect.Method;"+rt+
- "public class "+proxyClassName+" implements "+inter.getName()+" {"+rt+
- " public "+proxyClassName+"("+InHanderPackage+".InvocationHander h) {"+rt+
- " super();"+rt+
- " this.h = h;"+rt+
- " }"+rt+
- " private "+InHanderPackage+".InvocationHander h;"+rt+
- methodCode+rt+
- "}";
-
-
- String filename = System.getProperty("user.dir")+"/bin/"+packageName.replace(".", "//")+"/"+proxyClassName+".java";
- File file = new File(filename);
- try {
-
- FileUtils.writeStringToFile(file, javaCode);
- } catch (IOException e) {
- e.printStackTrace();
- }
-
-
-
- JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
-
- StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
-
- Iterable units = fileMgr.getJavaFileObjects(filename);
-
-
- CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
-
- t.call();
- try {
- fileMgr.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
-
- ClassLoader cl = ClassLoader.getSystemClassLoader();
- try {
- Class c = cl.loadClass(packageName+"."+proxyClassName);
- Constructor ctr = c.getConstructor(InvocationHander.class);
- return ctr.newInstance(h);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- }
4 測試ui
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
- public class TestProxy {
- @Before
- public void before(){
- System.out.println("-----------------start-------------------");
- }
- @Test
- public void test() {
- Book book = new Book();
- InvocationHander h = new ProxyHander(book);
- BookInterface bi = (BookInterface)Proxy.newProxyInstance(BookInterface.class,h);
- bi.selling();
-
- System.out.println("==================分割==============================");
-
- PhoneInterface car = new VivoPhone();
- h = new ProxyHander(car);
- PhoneInterface pi = (PhoneInterface)Proxy.newProxyInstance(PhoneInterface.class,h);
- pi.selling();
- }
- @After
- public void after(){
- System.out.println("-----------------end-------------------");
- }
- }
Proxy類裏面生成代理類名稱的方法是根據包名來的,全類名長度加起來超過250多個長度可能會讓java類沒法編譯,那就須要特殊處理了。超過250個長度的全類名那種項目沒見過,不考慮this
上面是他的原理,spring中如何使用aop呢?
請參考
參考文章