spring创建aop实现方式(对于Spring的AOP的实现方式,下列选项说法错误的是()(多选))
本文目录
- 对于Spring的AOP的实现方式,下列选项说法错误的是()(多选)
- spring aop 实现有几种方式
- 如何利用Spring编写一个aop的例子
- spring aop 用什么实现
- 实现Spring AOP 应用的几种方式
- spring配置aop的方式有哪些
- spring 的AOP实现机制有哪些
对于Spring的AOP的实现方式,下列选项说法错误的是()(多选)
选AD。
A错在advice就是用配置实现的,或者用annotation。
advice可以理解成是切面里写的具体的代码,pointcut可以理解为这些代码要放到程序的哪个地方,一版pointcut配合expression表达式来一起用。
在Spring中Advisor是Advice和Pointcut的结合,但它还不是AOP概念上的Aspect。因为在Spring中Advisor还是Spring用来生成Aspect对象的一个原型,根据配置的不同,Spring可以只对某个类生成Aspect,也可以对所有的类生成Aspect。
扩展资料:
Spring是全面的和模块化的。Spring有分层的体系结构,这意味着你能选择使用它孤立的任何部分,它的架构仍然是内在稳定的。例如,你可能选择仅仅使用Spring来简单化JDBC的使用,或用来管理所有的业务对象。
它的设计从底部帮助你编写易于测试的代码。Spring是用于测试驱动工程的理想的framework。
Spring对你的工程来说,它不需要一个以上的framework。Spring是潜在地一站式解决方案,定位于与典型应用相关的大部分基础结构。它也涉及到其他framework没有考虑到的内容。
参考资料来源:百度百科-spring
spring aop 实现有几种方式
选AD,A:错在advice就是用配置实现的,或者用annotation.D:错就不用说了吧,其它的,应该都是对的。
如何利用Spring编写一个aop的例子
打开Eclipse,新建Demo工程供编写测试程序使用。
导入编写测试程序使用到jar包。
注意:使用注解方式,必须引入aspectjrt和aspectjweaver包。
下面万事俱备,只欠东风了。开始编写测试程序。编写测试使用的接口类EatInter。
编写接口实现类,实现接口中的方法。
编写aop的通知类,此部分可以看作为公共模块要实现的功能。
修改Spring的applicationContext.xml配置文件。可以看到使用注解方式时,配置文件是非常简洁的。只需要编写红框中的代码即可。
做完以上工作后,我们可以编写测试用的主类了。执行以下主类,查看测试结果。此时可以看到通知类中的公共代码也全部执行。
spring aop 用什么实现
前面在学习代理模式的时候,了解到代理模式分为动态代理和静态代理。现在我们就以代理模式为基础先实现我们自己的AOP框架,再来研究Spring的AOP的实现原理。
先以静态代理实现,静态代理关键是在代理对象和目标对象实现共同的接口,并且代理对象持有目标对象的引用。
公共接口代码:
1 public interface IHello {2 /**3 * 业务方法4 * @param str5 */6 void sayHello(String str);7 }
目标类代码:
1 public class Hello implements IHello{2 @Override3 public void sayHello(String str) {4 System.out.println("hello "+str);5 }6 7 }
代理类代码,我们给它添加日志记录功能,在方法开始前后执行特定的方法,是不是和AOP特别像呢?
public class ProxyHello implements IHello{private IHello hello;public ProxyHello(IHello hello) { super(); this.hello = hello;}@Override public void sayHello(String str) {Logger.start();//添加特定的方法 hello.sayHello(str);Logger.end();}}
日志类代码:
1 public class Logger {2 public static void start(){3 System.out.println(new Date()+ " say hello start...");4 }5 6 public static void end(){7 System.out.println(new Date()+ " say hello end");8 }9 }
测试代码:
1 public class Test {2 public static void main(String args) {3 IHello hello = new ProxyHello(new Hello());//如果我们需要日志功能,则使用代理类4 //IHello hello = new Hello();//如果我们不需要日志功能则使用目标类5 hello.sayHello("明天"); 6 }7 }
这样我们就实现了一个最简单的AOP,但是这样会存在一个问题:如果我们像Hello这样的类很多,那么,我们是不是要去写很多个HelloProxy这样的类呢。其实也是一种很麻烦的事。在jdk1.3以后,jdk跟我们提供了一个API java.lang.reflect.InvocationHandler的类, 这个类可以让我们在JVM调用某个类的方法时动态的为些方法做些什么事。下面我们就来实现动态代理的实现。
动态代理实现主要是实现InvocationHandler,并且将目标对象注入到代理对象中,利用反射机制来执行目标对象的方法。
接口实现与静态代理相同,代理类代码:
1 public class DynaProxyHello implements InvocationHandler{ 2 3 private Object target;//目标对象 4 /** 5 * 通过反射来实例化目标对象 6 * @param object 7 * @return 8 */ 9 public Object bind(Object object){10 this.target = object;11 return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);12 }13 14 @Override15 public Object invoke(Object proxy, Method method, Object args)16 throws Throwable {17 Object result = null;18 Logger.start();//添加额外的方法19 //通过反射机制来运行目标对象的方法20 result = method.invoke(this.target, args);21 Logger.end();22 return result;23 }24 25 }
测试类代码:
1 public class DynaTest {2 public static void main(String args) {3 IHello hello = (IHello) new DynaProxyHello().bind(new Hello());//如果我们需要日志功能,则使用代理类4 //IHello hello = new Hello();//如果我们不需要日志功能则使用目标类5 hello.sayHello("明天");6 }7 }
看完上面的代码可能和Spring AOP相比有一个问题,日志类只能在方法前后打印,但是AOP应该是可以在满足条件就可以执行,所有是否可以将DynaPoxyHello对象和日志操作对象(Logger)解耦呢?
看下面代码实现,将将DynaPoxyHello对象和日志操作对象(Logger)解耦:
我们要在被代理对象的方法前面或者后面去加上日志操作代码(或者是其它操作的代码),那么,我们可以抽象出一个接口,这个接口里就只有两个方法:一个是在被代理对象要执行方法之前执行的方法,我们取名为start,第二个方法就是在被代理对象执行方法之后执行的方法,我们取名为end。
Logger的接口:
1 public interface ILogger {2 void start(Method method);3 void end(Method method);4 }
Logger的接口实现:
1 public class DLogger implements ILogger{ 2 @Override 3 public void start(Method method) { 4 System.out.println(new Date()+ method.getName() + " say hello start..."); 5 } 6 @Override 7 public void end(Method method) { 8 System.out.println(new Date()+ method.getName() + " say hello end"); 9 }10 }
动态代理类:
1 public class DynaProxyHello1 implements InvocationHandler{ 2 //调用对象 3 private Object proxy; 4 //目标对象 5 private Object target; 6 7 public Object bind(Object target,Object proxy){ 8 this.target=target; 9 this.proxy=proxy;10 return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);11 }12 13 14 @Override15 public Object invoke(Object proxy, Method method, Object{method});30 return result;31 }32 33 }
测试代码:
1 public class DynaTest1 {2 public static void main(String args) {3 IHello hello = (IHello) new DynaProxyHello1().bind(new Hello(),new DLogger());//如果我们需要日志功能,则使用代理类4 //IHello hello = new Hello();//如果我们不需要日志功能则使用目标类5 hello.sayHello("明天");6 }7 }
通过上面例子,可以发现通过动态代理和发射技术,已经基本实现了AOP的功能,如果我们只需要在方法执行前打印日志,则可以不实现end()方法,这样就可以控制打印的时机了。如果我们想让指定的方法打印日志,我们只需要在invoke()方法中加一个对method名字的判断,method的名字可以写在xml文件中,这样我们就可以实现以配置文件进行解耦了,这样我们就实现了一个简单的spring aop框架。
实现Spring AOP 应用的几种方式
spring开发aop应用有三种方法:一:Spring 1.2版本中通过ProxyFactoryBean来实现aop,即通过动态代理来实现的,Aspect必须继承MethodBeforeAdvice,MethodAfterAdvice等《!--被代理的对象--》《bean id="man" class="Man"》《property name="name"》《value type="java.lang.String"》张三《/value》《/property》《/bean》《!--继承了MethodBeforeAdvice类的 Aspect-》《bean id="fbi" class="FBI" /》《bean id="civilian"class="org.springframework.aop.framework.ProxyFactoryBean"》《property name="target"》《ref bean="man" /》《/property》《property name="interceptorNames"》《list》《value》fbi《/value》《/list》《/property》《/bean》二:Spring 2.0 AOP 应用需要改的是FBI 这个类,而且它也不需要再实现某些接口了public class FBI {public void before(JoinPoint point){Man man = (Man)point.getTarget();System.err.println("FBI 发现" + man.getName() + "正在进行 " +point.getSignature().getName() + " 活动。");}}注意这个类里面的方法 before(JoinPoint),方法名可以是任意的,可以带一个JoinPoint 类型的参数,也可以不带参数直接写成before(),但是这个连接点(JoinPoint)对象带来了所有和这次方法调用有关的信息,包括方法参数,目标对象等等,所以一般要做日志记录的话会带上它。接下来是测试类的代码,和以前的几乎没有任何不同,只不过现在直接访问的是man***隐藏网址******隐藏网址******隐藏网址***xsi:schemaLocation="***隐藏网址******隐藏网址******隐藏网址******隐藏网址***《bean id="fbi" class="FBI" /》《bean id="man" class="Man"》《property name="name"》《value type="java.lang.String"》张三《/value》《/property》《/bean》《aop:config》《aop:pointcut id="manPointcut"expression="execution(* Man.*(..))" /》《aop:aspect id="beforeExample" ref="fbi"》《aop:before pointcut-ref="manPointcut" method="before" /》《/aop:aspect》《/aop:config》《/beans》1. 配置文件的开头加入了aop 命名空间,如代码中粗斜体所示。2. 使用aop:config 标签来定义AOP,不是使用ProxyFactoryBean 来定义一个新的bean。一个是人的对象,另一个则是联邦调查局的探员。而aop:config 中定义了所有的AOP 设置信息。aop:pointcut定义了一个切入点,id 给出了这个切入点的唯一名字,而expression 定义了切入点的表达式,那么这个定义到底表示了什么信息呢?它的意思是表示一种场景,即执行(execution)Man 对象的所有方法的这种情况,这就是表达式execution(* Man.*(..))的意义所在,Man.*(..)表示Man 类的所有方法。接下来呢,需要定义一个切面,用aop:aspect 来定义,它的ref 属性指定了这个切面所对应的bean 定义的id,这里指向fbi 这个bean 类;子标签aop:before 则指示了当发生了名为manPointcut 的切入点(情况)前(用pointcut-ref 属性指定,pointcut-ref=”manPointcut”),就调用名为before 的方法,这个方法位于aspect 里面的引用的那个bean 中,这里是fbi(即ref=”fbi”)。其实Spring 执行到这里后,会自动的把这些代码翻译成底层的Bean 定义(后台依然会采用ProxyFactoryBean 这样的机制),然后把对应的获取bean 的操作直接委托给代理类,这就是为什么上文提到的测试类只需要访问原来的man 这个bean,对应的拦截类就会被执行的原因。从这里看到Spring 2.0 中要定义一个AOP 的bean 类,仍然是比较复杂的,XML 文件和概念都增加了很多,需要读者慢慢来学习和理解。三使用标注(@AspectJ)实现AOP的一个库来做切点(pointcut)解析和匹配。为了在Spring 配置中使用@AspectJ aspects,你必须首先启用Spring 对基于@AspectJaspects 的配置支持,自动代理(autoproxying)基于通知是否来自这些切面。 自动代理是指Spring 会判断一个bean 是否使用了一个或多个切面通知,并据此自动生成相应的代理以拦截其方法调用,并且确认通知是否如期进行。通过在你的Spring 的配置文件中引入下列元素来启用Spring 对@AspectJ 的支持:《aop:aspectj-autoproxy/》也可以通过在你的application context 中添加如下定义来启用@AspectJ 支持:《beanclass="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" /》你需要在你的应用程序的classpath 中引入两个AspectJ 库:aspectjweaver.jar 和aspectjrt.jar。我们这里用的MyEclipse,在添加Spring 开发功能时已经自动的加入了这些类库文件,无需手工配置了。定义切面Aspect:在启用@AspectJ 支持的情况下,在application context 中定义的任意带有一个@Aspect 切面(拥有@Aspect 标注)的bean 都将被Spring 自动识别并用于配置在Spring AOP。定义切入点Pointcut:现在通过在 @AspectJ 标注风格的 AOP 中,一个切入点签名通过一个普通的方法定义来提供,并且切入点表达式使用 @Pointcut 标注来表示(作为切入点签名的方法必须返回 void 类型)。代码可以参考清单10.12。好了,引用了这么些文档,我们需要介绍这个基于标注的新的AOP项目了,这个项目的名字是Spring2_0AOPAspectJ,如前一节所示加入了Spring核心和AOP类库后,就可以开发了。那么相比较10.4.1 使用aop 标签实现AOP一节,这一个项目的代码仅仅有两个地方要改。首先我们要修改FBI类的源码,加入标注来实现切面和切入点定义,如下所示:import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;/*** 联邦调查局的探员将您的所有行动都记录在案。* @author BeanSoft*/@Aspectpublic class FBI {@Before("execution(* Man.*(..))")public void before(JoinPoint point){Man man = (Man)point.getTarget();System.err.println("FBI 发现" + man.getName() + "正在进行 " +point.getSignature().getName() + " 活动。");}}清单10.12 加入了Aspect 标注的FBI 类这个类中的@Before 后面的"execution(* Man.*(..))"是切入点所对应的切入点点表达式,其意义和上一节的是一致的,仍然表示的是执行 Man 类的所有方法时将触发此方法的执行。使用了这种写法后,XML 配置文件将大大简化,其内容如下所示:《?xml version="1.0" encoding="UTF-8"?》***隐藏网址******隐藏网址******隐藏网址******隐藏网址***xsi:schemaLocation="***隐藏网址******隐藏网址******隐藏网址******隐藏网址******隐藏网址******隐藏网址***《aop:aspectj-autoproxy/》《bean id="fbi" class="FBI" /》《bean id="man" class="Man"》《property name="name"》《value type="java.lang.String"》张三《/value》《/property》《/bean》《/beans》1. 加入了粗斜体的《aop:aspectj-autoproxy/》定义;2. 去掉了《aop:config》标签部分。可以看到使用这种方式后,AOP 的开发和配置变的极其简单。这就是JDK 1.5 引入标注开发后带来的好处。当然弱点嘛,那就是要修改配置必须重新编译源代码了。注意:在这里你不能去掉《bean id="fbi" class="FBI" /》这一个bean的定义,否则自动AOP代理对象就没有机会被创建并工作了,那样的话man对象被代理也就无从谈起了。四开发环绕通知(Around Advice)AOP 应用@Aspectpublic class FBI {@Around("execution(* Man.*(..))")public Object before(ProceedingJoinPoint point) throws Throwable {Man man = (Man)point.getTarget();System.err.println("FBI 发现" + man.getName() + "即将正在进行 " +point.getSignature().getName() + " 活动。");// 禁止张三泡MMif(point.getSignature().getName().equals("mm")) {System.err.println("FBI 将阻止 " + man.getName() + " 泡MM。");} else if(point.getSignature().getName().equals("sayHelp")) {System.err.println("FBI 将欺骗 " + man.getName() + " 的朋友告诉他们他很好。");return "我是 " + man.getName() + " ,我现在过的很好。";} else {Object object = point.proceed();《br》System.err.println("FBI 发现" + man.getName() + "已经完成了 " +《br》point.getSignature().getName() + " 活动。");《br》return object;《br》}return null;}}现在张三不光是不能泡MM 了,当他求救的时候,FBI 还可以直接拦截并修改,将其请求的信息“救我,我是张三!”改成“我是张三,我现在过的很好。”,这样通过欺骗行为,张三的朋友永远也不知道发生了什么事。/*** 具有聊QQ和泡MM以及求救三个行为的人对象,还有一个用户名属性。* @author BeanSoft*/public class Man {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public void qq() {System.out.println("我在聊QQ");}public void mm() {System.out.println("我在泡MM");}public String sayHelp() {return "救我,我是" + getName();}}
spring配置aop的方式有哪些
在Spring中实现AOP根据版本不同,可以有大致四种配置方式。现简单列一下。在介绍Spring的AOP配置方式前,先要注意Spring中Advisor的概念。在Spring中Advisor是Advice和Pointcut的结合,但它还不是AOP概念上的Aspect。因为在Spring中Advisor还是Spring用来生成Aspect对象的一个原型,根据配置的不同,Spring可以只对某个类生成Aspect,也可以对所有的类生成Aspect。1. 基于xml配置文件的代理配置方式这种方式在2.0以后很少用了,原因是配置项过多,过于繁琐。但对于理解Spring AOP还是很有帮助的1.1 定义通知《bean id="advice" class="yourAdviceImpl" /》1.2 定义切点要定义一个切点,可以选择使用正则表达式方式声明的切点或者AspectJ方式声明的切点。对正则表达式切点,使用Perl5RegexpMethodPointcut或JdkRegexpMethodPointcut(Java 1.4以上版本,不需要Jakarta ORO的支持了);对AspectJ切点,使用AspectJExpressPointcut《bean id="pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"》 《property name="pattern" value="yourRegularExpression" /》《/bean》《bean id="pointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcut"》 《property name="expression" value="yourAspectJExpression" /》《/bean》1.3 定义通知者DefaultPointcutAdvisor是Spring提供的默认通知者,它需要提供通知和切点的引用。Spring也提供了RegexpMethodPointcutAdvisor和AspectJExpressionPointcutAdvisor来对应两种声明切点的方式,不用再单独定义切点。《bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"》 《property name="advice" ref="advice" /》 《property name="pointcut" ref="pointcut" /》《/bean》《bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"》 《property name="advice" ref="advice" /》 《property name="pattern" value="yourRegularExpression" /》《/bean》《bean id="advisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcut"》 《property name="advice" ref="advice" /》 《property name="expression" value="yourAspectjExpression" /》《/bean》1.4 定义ProxyFactoryBean《bean id="yourBean" class="org.springframework.aop.framework.ProxyFactoryBean》 《property name="target" ref="yourTargetBean" /》 《property name="interceptorNames" value="advisor" /》 《property name="proxyInterfaces" value="interfaceClass" /》《/bean》interceptorNames和proxyInterfaces都是数组属性,所以可以声明要使用的一个list,也可以让Spring自动把单个值转化为数组上面明确定义了要对那个targetBean应用代理生成切面实例。如果不想限制targetBean,可以让Spring为所有匹配切点声明的bean生成切面实例,这样就不用一个个定义ProxyFactoryBean了,只需要定义《bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" /》这是一个BeanPostProcessor,所以Spring会自动识别并在bean的声明周期使用2 利用2.0以后使用aop标签《aop:config》 《aop:aspect ref=""》 《aop:pointcut id="performance" expression="execution(* *.perform(..))" /》《aop:before method="" pointcut-ref="performance" /》《aop:before method="" pointcut="execution(* *.perform(..))" /》《aop:after-returning method="" pointcut="execution(* *.perform(..))" /》《aop:after-throwing method="" pointcut="execution(* *.perform(..))" /》 《/aop:aspect》《/aop:config》3 利用Annotation3.1 利用@Aspect将一个POJO类声明为一个切面。3.2 定义切点@Pointcut("execution(* *.perform(..))")public void performance(){}通过@Pointcut定义的切点的名字就是它所注解的方法的名字,因此例子中的切点名字是performance()。这里声明的performance()方法实际圣只是一个标记,为@Pointcut提供附加的点,并不要求有实际意义。3.3 定义通知对要执行切面的方法,通过@Before("performance()"),@AfterReturning("performance()")来定义通知。注意这里提供的切点名称,是performance(),而不是performance如果对上面的两点不是很理解,也可以省略@Pointcut,而将AspectJ表达式直接定义在@Before等通知中,将上面的两步合为一步,如@Before("execution(* *.perform(..))")3.4 通知Spring创建代理《aop:aspectj-autoproxy》这实际上相当于声明了一个AnnotationAwareAspectJAutoProxyCreator,从而根据@Pointcut声明的切点来自动代理匹配的bean实例4 在Spring中结合进AspectJ对于超出Spring AOP支持范围的,可以采用这种方式。只需要在Spring中配置AspectJ的Class实例时让Spring能够获得AspectJ类的实例就可以了,比如《bean class="a_aspectj_class" factory-method="aspectOf"》 《preperty .... /》《/bean》
spring 的AOP实现机制有哪些
SPRING是通过动态代理来实现AOP的,SPRING内部提供了2种实现机制1.如果是有接口声明的类进行AOP,spring调用的是java.lang.reflection.Proxy类来做处理org.springframework.aop.framework.JdkDynamicAopProxy public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { Class targetClass = this.advised.getTargetSource().getTargetClass(); logger.debug(“Creating JDK dynamic proxy” + (targetClass != null ? ” for ” : “”)); } Class proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }org.springframework.aop.framework.ReflectiveMethodInvocationpublic Object proceed() throws Throwable { // We start with an index of -1 and increment early. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() – 1) { return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { // It’s an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }2.如果是没有接口声明的类呢?SPRING通过CGLIB包和内部类来实现private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable { private final Object target; public StaticUnadvisedInterceptor(Object target) {this.target = target;} public Object intercept(Object proxy, Method method, Object args, MethodProxy methodProxy) throws Throwable {Object oldProxy = null;Object target = advised.getTargetSource().getTarget();try {oldProxy = AopContext.setCurrentProxy(proxy);Object retVal = methodProxy.invoke(target, args);return massageReturnTypeIfNecessary(proxy, target, retVal);}finally {AopContext.setCurrentProxy(oldProxy);advised.getTargetSource().releaseTarget(target);}}} 我们自己也可以来试试1.jdk proxy方式先来一个接口IHelloWorld.javapackage kris.aop.test; public interface IHelloWorld { public void print(String name);public void write(String sth);} 再来一个实现HelloWorld.javapackage kris.aop.test; public class HelloWorld implements IHelloWorld { public void print(String name){System.out.println(“HelloWorld “+name);} public void write(String sth) {System.out.println(“write “+sth);} } 代理类DefaultInvocationHandler.javapackage kris.aop.test; import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method; public class DefaultInvocationHandler implements InvocationHandler { /*** 替换外部class调用的方法* obj 外部已经已经包装好InvocationHandler的实例* method 外部方法* args 方法参数*/public Object invoke(Object obj, Method method, Object={“anyone”};IHelloWorld ihw=new HelloWorld();System.out.println(“start!”);method.invoke(ihw,args);method.invoke(ihw,s1);Object o=method.invoke(ihw,s2);System.out.println(“stop!”);return o;}} 测试类Test.javapackage kris.aop.test; import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy; public class Test { public static void main(String args args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(HelloWorld.class);//设置回调方法实现类enhancer.setCallback(new MethodInterceptorImpl());//实例化已经添加回调实现的HELLOWORLD实例HelloWorld my = (HelloWorld) enhancer.create(); my.print();} }
更多文章:
u盘显示需要格式化才能用怎么办(U盘不能用了 说要先格式化才能打开 什么回事啊)
2024年6月14日 04:23
windows 10 mobile(如何安装win10 mobile)
2024年7月24日 12:51
erp系统软件免费下载(哪里有免费的ERP生产管理软件下载)
2024年8月12日 13:45
英语alter和change区别是什么?change和alter有什么区别
2024年8月19日 06:46
比特币现在国际行情是怎样的?比特币最近的行情怎样为哪位大咖可以来回答一下
2024年8月30日 16:55
ice princess(请问《冰雪公主》(iceprincess)中的英文歌曲的名字)
2024年1月27日 05:20
为什么我电脑迅雷加速器会员支付页面都打不开?着个CF的加速器叫什么来着
2024年6月28日 01:33