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呢?
请参考
参考文章