- 浏览: 189465 次
- 性别:
- 来自: 杭州
博客专栏
-
Java技术分享
浏览量:0
文章分类
最新评论
-
masuweng:
学习了,学习了
mybatis是如何防止SQL注入的 -
somefuture:
终于知道了#$的区别
mybatis是如何防止SQL注入的 -
masuweng:
...
tomct处理请求的流程 -
zhp8341:
masuweng 写道寻求cas的更多例子, http://w ...
JUC之CAS -
臻是二哥:
java.util.concurrent包中到处都使用了CAS ...
JUC之CAS
用java实现AOP主要用到了java反射机制,java动态代理,java注释。分别对应java.lang.reflect;java.lang.annotation包。关于自定义注释这里不再讲,请看代码:
定义Aop注释
定义Aop切入的方法
下面是Aop功能的实现,在这里,我想说下java的动态代理功能,好多人对java动态代理的机制理解不深,小编也曾经困惑过:
java动态代理机制说白了就是两个主要的方法,一个是Proxy类的static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法,这是一个静态方法,返回代理类实例。
还有一个就是InvocationHandler类的 Object invoke(Object proxy, Method method, Object[] args) 方法,这个方法是调用处理程序。
来看我们的Aop实现类:
这是要实现Aop的接口:
下面是Aop要植入的方法所在的类:
下面是测试类:
以上面的例子为例,我们继续来说java动态代理,本来在Test中,我们可以使用new Factory().sell()来买东西,但一段时间之后,发现光买东西不行,得赠送礼品顾客才能买我的产品,这就是Aop要解决的问题,这个时候怎么办呢?
当然你可以修改Factory类,但是软件的OCP原则不允许我们这么做,因此,我们要使用Aop编程。
首先在Test类中,我们建立了new Factory()这个对象的代理对象s,由bind的两个参数可知,代理对象实例s要代理new Factory()对象,并且仅仅代理Sell接口中的那些方法,在看看sell接口中的方法,于是,我们可以理解,其实在代理实例s中存储了他要代理的对象new Factory()的InvocationHandler对象new AopConsole(new Factory())以及要代理的方法sell(),要注意这个sell方法是代理实例s从Sell接口中了解到的,好了至此,我们知道了代理对象里面都是什么内容。
接着Test中的第二句s.sell();语句,java动态代理机制在执行这个语句时就起作用了,首先他会查看s能代理sell吗?已查看实现的接口,发现能代理sell,这个时候,执行new AopConsole(new Factory()).invoke(Object proxy,Method method,Object[] args) throws Throwable
;也就是说执行InvocationHandler类的invoke方法,此时,new Factory()就是我们在Test只能怪传入的那个Factory对象,method就是sell方法,参数就是Test中sell方法的参数,这里为null,而proxy自然是代理类对象s,自此,因此可以知道在InvocationHandler类的invoke中,使用method.invoke(obj,args);而不是用method.invoke(proxy,args)至于代理的时候,还要增加什么操作,就自己说的算了,反正被代理方法的只用由method.invoke(obj,args)就可以完成。
这个例子中,笔者尝试的写了一个类似Spring中实现通过注释实现AOP的功能,由于仅仅是为了研究动态代理,所以仅仅支持方法参数是String类型的,其他类型,读者可以自行扩展。
另外,容易犯错的是,实现AOP的时候,实现AOP的注释一定要在接口中声明,在本例子中,就是Sell接口中,在Factory中注释是无效的,运行报错,至于其中缘由,已经在文章中的红体字说明,不再赘述。
定义Aop注释
import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Aop { String className(); String methodName(); String methodArgs() default ""; String argTypes() default ""; AopPolicy policy() ; }
定义Aop切入的方法
public enum AopPolicy { Begin,End }
下面是Aop功能的实现,在这里,我想说下java的动态代理功能,好多人对java动态代理的机制理解不深,小编也曾经困惑过:
java动态代理机制说白了就是两个主要的方法,一个是Proxy类的static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法,这是一个静态方法,返回代理类实例。
还有一个就是InvocationHandler类的 Object invoke(Object proxy, Method method, Object[] args) 方法,这个方法是调用处理程序。
来看我们的Aop实现类:
import java.lang.reflect.*; import java.util.*; public class AopConsole implements InvocationHandler { public Object obj;//代理的实际对象 public AopConsole(){} public AopConsole(Object obj) { this.obj=obj; } public static Object bind(Class[] interfaces,Object obj) { return Proxy.newProxyInstance(interfaces[0].getClassLoader(),interfaces,new AopConsole(obj)); } public static Object bind(Class a,Object obj) { return bind(new Class[]{a},obj); } /** *proxy为代理类的一个实例 *method为代理的那个方法,这个方法使用的地址是接口中的那个方法的地址,一定要注意 *args为代理的那个方法的参数 */ public Object invoke(Object proxy,Method method,Object[] args) throws Throwable { Object result=null; Object obegin=null,oend=null; Method mbegin=null,mend=null; /************以下部分为 获取被代理的方法的AOP注释的内容**************/ Aop aop = method.getAnnotation(Aop.class);//得到这个方法的注释,这个注释一定是在接口中的注释,因为这是java的反射机制是基于接口的 String aopClassName = aop.className(); String aopMethodName=aop.methodName(); String methodArgs=aop.methodArgs(); String argTypes=aop.argTypes(); AopPolicy aopPolicy=aop.policy(); /************以上部分为 获取被代理的方法的AOP注释的内容**************/ /************以下部分为找出在AOP中药切入的方法调用 ,也就是对obegin,oend,mbegin,mend赋值 **/ Class aopClass=Class.forName(aopClassName); Method[] methods = aopClass.getMethods(); boolean flag=false; for(int i=0;i<methods.length;i++) { //对于AOP要调用的方法 if((methods[i].getName().equals(aopMethodName))&&(getMethodParamTypes(methods[i]).equals(argTypes))) { if(aopPolicy==AopPolicy.Begin) { obegin=aopClass.newInstance(); mbegin=methods[i]; } else if (aopPolicy==AopPolicy.End) { oend=aopClass.newInstance(); mend=methods[i]; } flag=true; } } if(flag==false) { System.out.println("找不到AOP注释中要切入的方法"); } /*****以上部分为找出在AOP中药切入的方法调用 ,也就是对obegin,oend,mbegin,mend赋值*********/ /****以下部分为进行AOP增强处理*********/ if(obegin!=null) { mbegin.invoke(obegin,getMethodArgs(methodArgs));//AOP附加的方法 } result=method.invoke(obj,args);//注意,此处为proxy(代理类对象),而非obj(代理实例对象) if(oend!=null) { mend.invoke(oend,getMethodArgs(methodArgs));//AOP附加的方法 } return result;//此处返回原方法的调用结果,正好符合了aop编程的实际情况 /****以上部分为进行AOP增强处理********/ } /** *以String形式返回method方法的参数类型 *没有参数时候,返回"" *有参数时,例如返回int,java.lang.String,java.lang.String */ private static String getMethodParamTypes(Method method) { //返回参数类型,用String表示 Class [] paramTypes=method.getParameterTypes(); String paramTypes_str=""; if(paramTypes.length!=0) { StringBuffer sb=new StringBuffer(""); for(int j=0;j<paramTypes.length;j++) { sb.append(paramTypes[j].getName()+","); } paramTypes_str=sb.substring(0,sb.length()-1); } return paramTypes_str; } /** *将String类型的methodArgs转换为Obj[] */ private static Object[] getMethodArgs(String methodArgs) { Object [] aopArgs=null; if(!("".equals(methodArgs))) { aopArgs=methodArgs.split(","); } return aopArgs; } }
这是要实现Aop的接口:
public interface Sell { //@Aop(className="Present",methodName="give",methodArgs="",policy=AopPolicy.Begin) //@Aop(className="Present",methodName="give",methodArgs="liming",argTypes="java.lang.String",policy=AopPolicy.End) @Aop(className="Present",methodName="give",methodArgs="present,liming",argTypes="java.lang.String,java.lang.String",policy=AopPolicy.End) public void sell(); }
public class Factory implements Sell { public void sell() { System.out.println("卖产品"); } }
下面是Aop要植入的方法所在的类:
public class Present { public void give(String sth,String name) { System.out.println("送"+sth+" 给 "+name); } public void give(String name) { System.out.println("送礼品给 "+name); } public void give() { System.out.println("送礼品"); } }
下面是测试类:
public class Test { public static void main(String [] args) { Sell s=(Sell)AopConsole.bind(Sell.class,new Factory()); s.sell(); } }
以上面的例子为例,我们继续来说java动态代理,本来在Test中,我们可以使用new Factory().sell()来买东西,但一段时间之后,发现光买东西不行,得赠送礼品顾客才能买我的产品,这就是Aop要解决的问题,这个时候怎么办呢?
当然你可以修改Factory类,但是软件的OCP原则不允许我们这么做,因此,我们要使用Aop编程。
首先在Test类中,我们建立了new Factory()这个对象的代理对象s,由bind的两个参数可知,代理对象实例s要代理new Factory()对象,并且仅仅代理Sell接口中的那些方法,在看看sell接口中的方法,于是,我们可以理解,其实在代理实例s中存储了他要代理的对象new Factory()的InvocationHandler对象new AopConsole(new Factory())以及要代理的方法sell(),要注意这个sell方法是代理实例s从Sell接口中了解到的,好了至此,我们知道了代理对象里面都是什么内容。
接着Test中的第二句s.sell();语句,java动态代理机制在执行这个语句时就起作用了,首先他会查看s能代理sell吗?已查看实现的接口,发现能代理sell,这个时候,执行new AopConsole(new Factory()).invoke(Object proxy,Method method,Object[] args) throws Throwable
;也就是说执行InvocationHandler类的invoke方法,此时,new Factory()就是我们在Test只能怪传入的那个Factory对象,method就是sell方法,参数就是Test中sell方法的参数,这里为null,而proxy自然是代理类对象s,自此,因此可以知道在InvocationHandler类的invoke中,使用method.invoke(obj,args);而不是用method.invoke(proxy,args)至于代理的时候,还要增加什么操作,就自己说的算了,反正被代理方法的只用由method.invoke(obj,args)就可以完成。
这个例子中,笔者尝试的写了一个类似Spring中实现通过注释实现AOP的功能,由于仅仅是为了研究动态代理,所以仅仅支持方法参数是String类型的,其他类型,读者可以自行扩展。
另外,容易犯错的是,实现AOP的时候,实现AOP的注释一定要在接口中声明,在本例子中,就是Sell接口中,在Factory中注释是无效的,运行报错,至于其中缘由,已经在文章中的红体字说明,不再赘述。
发表评论
-
精心准备的讲解Java多线程的知乎Live
2018-09-02 21:39 704花了一个月的时间,结合自己的理解,制作了一个以图片的方式讲解J ... -
在知乎推出Java求职类专栏文章
2018-08-27 12:06 790从昨天起,笔者开始在知乎推出Java求职类专栏文章,主要涉及一 ... -
提高Java,我建议这样做
2018-01-04 20:28 229Java该怎么学,学到什么深度? 外包的同学,怎么做技术提升 ... -
JAVA授课
2017-05-09 10:17 167在跟谁学注册了一个账号,再想学Java的同学以后可以在上面找我 ... -
Java中的可变参数
2016-12-31 10:43 1181Java在1.5之后允许方法使 ... -
这样搞——保证你的代码没有try-catch
2016-12-21 07:56 1250常常听到有技术圈的朋友抱怨,尤其是从其他语言转到Java语言的 ... -
回调模式——让你的controller不再繁琐
2016-12-19 10:12 998在Java后台编程中,大家一般会使用MVC设计模式,即便使用的 ... -
玩转Spring!从拒绝Filter开始
2016-12-14 19:09 1007一直以来,博客都是在写一些读书笔记或者学习心得。俗话说,举一反 ... -
推荐JAVA学习路线
2016-12-13 11:06 1758一直以来,都想写一篇介绍Java学习路线的博客。为什么有这个想 ... -
JAVA的四种引用类型
2016-08-12 17:24 1283Java四种引用类型 1.引用的基本概念 强引用:当我们使用 ... -
Time33算法与位运算
2016-05-19 19:55 1242最近不是很忙,阅读了下《大型网站技术架构》一书。在4.3.4代 ... -
hashCode和equals
2016-05-04 19:48 463最近在复习的时候,又 ... -
中英文混合排序
2015-11-02 19:02 2080好久没有写博客了,期间在做桌面云,被要求保密哈。不过最近在写一 ... -
Exception in thread "main" java.util.ConcurrentModificationException
2014-09-22 10:45 1749最近写代码竟然烦了一个很低级的错误,写出来供大家参考: 在涉及 ... -
一个java并行小应用
2014-09-13 09:11 1206好久没写博客了,最近在研究fourinone框架,受到其启发, ... -
反射机制实现方法调用
2014-08-25 19:33 1236import java.lang.reflect.*; ... -
ScheduledThreadPoolExecutor
2014-08-20 09:58 273ScheduledThreadPoolExecutor是一个定 ... -
Synchronized
2014-08-19 21:09 353import java.util.*; import jav ... -
Lock
2014-08-19 16:47 500Lock是多线程访问共享资源的工具,通常情况下,一次只能有一个 ... -
一个自定义注释的例子
2014-08-19 10:17 945import java.lang.annotation.*; ...
相关推荐
以下是一个简单的示例,展示了如何使用Java反射API实现AOP: ```java import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ...
在本文中,我们将通过一个简单的例子来展示如何使用Java动态代理实现AOP。首先,我们定义了一个business接口和一个实现类BusinessObject,BusinessObject中包含了商业逻辑代码和日志记录代码。 ```java public ...
下面是一个简单的Java动态代理实现AOP的例子,模拟日志记录功能: ```java public interface MyInterface { void doSomething(); } public class MyTarget implements MyInterface { @Override public void ...
**AOP思想与Java实现** 面向切面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,它旨在解决传统面向对象编程中的横切关注点,如日志、事务管理、性能监控等,这些关注点往往分散在程序的各个角落,...
代码实现简单,易于维护:使用 Spring AOP 可以将耗时监测的逻辑与业务逻辑进行解耦,避免业务逻辑代码的冗余和代码维护难度的提高。 2. 安全性高:使用 Spring AOP 进行方法耗时监测,可以在不修改业务逻辑代码的...
为了简单起见,例子没有没有使用任何第三方的AOP Framework, 而是利用Java语言本身自带的动态代理功能来实现AOP. 让我们先回到AOP本身,AOP主要应用于日志记录,性能统计,安全控制,事务处理等方面。它的主要...
1.只需要在controller层增加自定义@RequestLog注解就可以实现了。 @RequestLog功能参数如下: 功能一:是否记录请求参数 功能二:是否记录请求日志 功能三:是否记录返回值 功能四:是否以debug形式记录 功能五:日志类型 ...
Java中的AOP(Aspect ...通过这些知识点,你可以理解并实现Java中的AOP编程,有效地管理和组织代码,提高软件的模块化程度。在实际项目中,AOP能够帮助你更好地管理横切关注点,让代码更加整洁,更易于测试和维护。
总之,Java动态代理和AOP提供了强大的工具,使我们能够优雅地实现代码解耦,提高代码的复用性和可维护性。通过代理对象,我们可以在不修改原始类代码的情况下,添加额外的功能或改变原有行为,这对于系统的服务层和...
Spring框架是Java中实现AOP的一个流行工具,它通过动态代理机制实现了这一功能。本文将深入探讨Spring AOP的实现原理,以及如何使用反射来实现动态代理模式。 首先,我们需要了解AOP的基本概念。AOP的核心思想是切...
9. 其他AOP框架:文档提及除了Spring AOP以外,还有JAC(Java Aspect Components)和Jboss AOP等其他AOP框架,这些都是Java生态中实现AOP的工具。 通过这些知识点,可以看出文档主要围绕Java动态代理的原理及其在...
在本项目"基于Bytebuddy的Java Agent AOP框架.zip"中,我们将探讨如何使用ByteBuddy构建一个简单的AOP框架。 首先,我们需要理解AOP的核心概念。AOP是一种编程范式,旨在提供一种方法来处理那些横切多个对象的共同...
Java 动态代理技术是Java平台提供的一种强大的编程机制,它允许我们在运行时创建具有特定接口的代理对象,这些代理对象可以对方法调用进行拦截和处理,这正是AOP(面向切面编程)的核心思想。在Java中,动态代理主要...
以下是一个简单的例子,展示了如何使用JDK动态代理实现AOP: 首先,我们需要一个基础接口,比如`Calculator`,它定义了我们的业务方法: ```java public interface Calculator { public int calculate(int a, int...
基于Spring boot + maven,以注解+AOP方式实现的java后端项目接口参数校验框架。迄今为止使用最简单、最容易理解的参数校验方案。博客地址:https://blog.csdn.net/weixin_42686388/article/details/104009771
在本项目中,我们将探讨如何通过配置文件实现Spring AOP,包括前置通知、后置通知以及拦截器的运用。 首先,我们需要理解Spring AOP的核心概念。切面(Aspect)是关注点的模块化,这些关注点定义了跨越多个对象的...
在这个“手写简单实现ioc、aop事务demo”中,我们将探讨如何通过工厂模式和动态代理来实现这些概念。 首先,让我们了解IOC的核心思想。在传统的编程中,对象创建和管理的控制权在程序员手中,而IOC则是将这种控制权...
在Java中,AOP通常通过Spring框架来实现,Spring提供了强大的AOP支持,允许开发者定义“切面”,这些切面可以封装横切关注点,如日志、事务管理、性能监控等。现在,我们将深入探讨Java中AOP的实现及其应用场景。 ...
而基于自动代理的AOP配置则相对简单: ```xml <aop:aspectj-autoproxy/> ``` 在`Spring_AopByProxy`和`Spring_AopByAutoProxy`这两个文件中,应该包含了相应的XML配置示例和对应的Java代码。通过研究这些示例,...