package com;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import com.service.TestService;
import com.service.impl.TestServiceImpl;
//当所代理对象有实现接口时
public class JDKProxy implements InvocationHandler {
private Object targetObject;
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
Object result = null;
result = Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
return result;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
TestServiceImpl bean = (TestServiceImpl) this.targetObject;
Object result = null;
if(bean.getTestDao() != null) {
//before advice()...前置通知
try {
result = method.invoke(this.targetObject, args);
//after advice()...后置通知
} catch (Exception e) {
//exception advice()...例外通知
} finally {
//finally advice()...最终通知
}
}
return result;
}
}
//当对应的TestSerice2没有实现接口的时候,可以使用CGlib来动态代理
class CGlibProxy implements MethodInterceptor {
private Object targetObject;
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
TestService bean = (TestService) this.targetObject;
Object result = null;
if(bean != null) {
result = methodProxy.invoke(this.targetObject, args);
}
return result;
}
}
//切面
@Aspect
class MyInterceptor {
@Pointcut("execution (* com.service.impl.*.*(..))")
private void anyMethod() {} //声明一个切入点
@Before("anyMethod() && args(name)")
public void add(String message) {
//只对满足anyMethod切入点的所有方法和只有一个参数的方法插入切入点
System.out.println(message + "前置通知");
}
@AfterReturning(pointcut="anyMethod()", returning="otherMess")
public void afterAdd(String otherMess) {
//只对返回值为String类型的方法插入切面并且返回的值作为切入方法的参数传入
System.out.println(otherMess + "后置通知");
}
@After("anyMethod() && args(name)")
public void finallyAdd(String finalMess) {
System.out.println(finalMess + "最终通知");
}
@AfterThrowing("anyMethod() && args(name)")
public void exceptionAdd(String exceptionMess) {
System.out.println(exceptionMess + "例外通知");
}
@Around("anyMethod()")
public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint)
throws Throwable {
Object result = null;
if (result == null) { //判断用户是否存在权限
System.out.println("into 环绕通知");
result = proceedingJoinPoint.proceed();
System.out.println("out 环绕通知");
}
return result;
}
}
//切面2 采用XMl的配置方式配置切面
class MyInterceptor2 {
private void anyMethod() {} //声明一个切入点
public void add(String message) {
//只对满足anyMethod切入点的所有方法和只有一个参数的方法插入切入点
System.out.println(message + "前置通知");
}
public void afterAdd(String otherMess) {
//只对返回值为String类型的方法插入切面并且返回的值作为切入方法的参数传入
System.out.println(otherMess + "后置通知");
}
public void finallyAdd(String finalMess) {
System.out.println(finalMess + "最终通知");
}
public void exceptionAdd(String exceptionMess) {
System.out.println(exceptionMess + "例外通知");
}
public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint)
throws Throwable {
Object result = null;
if (result == null) { //判断用户是否存在权限
System.out.println("into 环绕通知");
result = proceedingJoinPoint.proceed();
System.out.println("out 环绕通知");
}
return result;
}
}
//spring-aop.xml的XML切面配置
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
">
<!-- 基于XML配置方式声明切面 -->
<bean id="myInterceptor" class="com.MyInterceptor2"/>
<aop:config>
<aop:aspect id="myaop" ref="myInterceptor">
<!-- 声明一个切入点 -->
<aop:pointcut expression="execution(* com.service.impl.*(..))" id="myPointCut"/>
<!-- 前置通知 -->
<aop:before method="add" pointcut-ref="myPointCut"/>
<!-- 后置通知 -->
<aop:after-returning method="afterAdd" pointcut-ref="myPointCut"/>
<!-- 最终通知 -->
<aop:after method="finallyAdd" pointcut-ref="myPointCut"/>
<!-- 例外通知 -->
<aop:after-throwing method="exceptionAdd" pointcut-ref="myPointCut"/>
<!-- 环绕通知 -->
<aop:around method="aroundMethod" pointcut-ref="myPointCut"/>
</aop:aspect>
</aop:config>
</beans>
分享到:
相关推荐
这篇学习笔记主要关注动态代理部分,虽然没有提供具体的压缩包文件内容,但根据标题和描述,我们可以深入探讨这两个概念。 **反射(Reflection)** 反射是Java语言的一个强大工具,它允许程序在运行时检查类、接口...
总结来说,这个资源提供了一个理解和实践静态代理与动态代理的好例子。通过学习和运行这些代码,你可以深入理解这两种代理模式的工作原理,以及如何在实际项目中应用它们。同时,这也有助于提升你对Java反射机制的...
总结Java 动态代理为我们提供了在运行时创建代理对象的能力,减少了代码的冗余,提高了代码的灵活性。JDK 动态代理适用于目标类实现接口的情况,而 CGLIB 则可以处理无接口的类。了解和掌握动态代理技术对于深入理解...
总结一下,Spring Boot的动态代理主要通过AOP实现,可以使用JDK代理或CGLIB代理,这取决于目标对象是否实现了接口。动态代理使得我们可以在不修改原有业务代码的情况下,灵活地插入额外的功能,提高了代码的可维护性...
Java动态代理是Java编程中一个重要的特性,它允许我们在运行时创建代理对象,这些代理对象可以作为原有...希望这个总结能对你有所帮助,无论是学习还是工作中,理解并掌握动态代理都能让你在处理复杂系统时游刃有余。
总结来说,动态代理和工厂方法都是为了提升软件设计的灵活性和可扩展性。工厂方法通过封装对象的创建过程,使系统更加模块化;动态代理则允许我们在运行时扩展对象的行为,提供一种灵活的添加新功能的方式。在实际...
通过本文的学习,我们可以了解到Java动态代理的基本原理以及其实现过程。动态代理不仅可以用于扩展已有类的功能,还可以简化代码结构,提高程序的可维护性和扩展性。对于开发人员来说,掌握这一技术将有助于更好地...
总结,动态代理和CGLIB都是Java中实现AOP的关键技术,它们提供了在不修改源码的情况下扩展和增强已有功能的能力。根据实际需求,我们可以灵活选择适合的代理方式。在学习和应用这些技术时,理解其原理和使用场景至关...
总结来说,这个压缩包提供的资源对于学习和理解Java动态代理非常有价值。通过阅读文档可以掌握理论知识,通过分析源码可以加深对实际操作的理解。对于想提升Java编程技能,特别是涉及AOP和RPC开发的开发者来说,这是...
总结一下,"动态代理案例"主要涵盖了Java中的JDK动态代理和CGLIB动态代理的使用,通过这两个工具,开发者可以在不修改原始代码的情况下,为已有对象添加新的功能,实现代码的解耦和扩展。在深入学习这些案例后,将有...
总结来说,静态代理适用于代理类已知且相对固定的场景,而动态代理则更适用于代理类不固定或需要动态生成的情况,例如在AOP(面向切面编程)中,动态代理可以方便地实现切面逻辑。在实际开发中,应根据项目需求选择...
### Java动态代理实现AOP详解 #### 一、引言 随着软件开发复杂度的提升,传统的面向对象编程(OOP)已经...总之,通过本篇文章的学习,读者应该能够理解和掌握如何使用Java动态代理来实现AOP的基本原理及实践操作。
标题 "JDK动态代理在EJB3(包括WebService)中的应用" 暗示了本文将探讨Java开发中的一种重要技术——JDK动态代理,以及它如何在企业级...通过学习和熟练掌握动态代理,开发者可以更高效地构建和管理Java EE应用程序。
在Java编程中,动态代理是...对于学习和理解这两种动态代理机制,可以参考提供的博客链接,以及深入研究源码,这将有助于提升对Java动态代理的掌握。同时,熟悉这些工具能帮助开发者更好地设计和实现高效、灵活的代码。
在Java编程中,动态代理是一种强大的特性,它允许我们在运行时创建代理类,这些代理类可以代表或增强...在"ReflectProxyDemo"这个实例中,我们可以亲身体验到动态代理的强大之处,学习如何通过它来增强我们的应用程序。
总结,Java反射和动态代理是强大的工具,可以极大地提升代码的灵活性和可扩展性。"reflections"项目通过实践示例,让我们更直观地理解了这两个概念,对于学习和掌握Java高级特性的开发者来说,是非常宝贵的资源。
在Java编程领域,动态代理是一种强大的设计模式,它允许我们在运行时创建代理对象来扩展或增强已有对象的功能。...通过学习和熟练掌握动态代理,可以提高代码的复用性和可维护性,是每个Java开发者必备的技能之一。