package cn.itcast.service;
public interface PersonService {
public void save(String name);
public void update(String name, Integer personid);
public String getPersonName(Integer personid);
}
package cn.itcast.service.impl;
import cn.itcast.service.PersonService;
public class PersonServiceBean implements PersonService {
private String user = null;
public String getUser() {
return user;
}
public PersonServiceBean() {
}
public PersonServiceBean(String user) {
this.user = user;
}
public String getPersonName(Integer personid) {
System.out.println("我是getPersonName()方法");
return "xxx";
}
public void save(String name) {
System.out.println("我是save()方法");
}
public void update(String name, Integer personid) {
System.out.println("我是update()方法");
}
}
package cn.itcast.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import cn.itcast.service.impl.PersonServiceBean;
public class JDKProxyFactory implements InvocationHandler {
// 目标类
private Object targetObject;
public Object createProxyIntance(Object targetObject) {
this.targetObject = targetObject;
/*
* Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
* 第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器
* 第二个参数设置代理类实现的接口
* 第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法
*/
return Proxy.newProxyInstance(this.targetObject.getClass()
.getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
}
// 该方法自动调用
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {// 环绕通知
PersonServiceBean bean = (PersonServiceBean) this.targetObject;
Object result = null;
if (bean.getUser() != null) {
// ..... advice()-->前置通知
try {
result = method.invoke(targetObject, args); // 把方法调用委派给目标对象
// afteradvice() -->后置通知
} catch (RuntimeException e) {
// exceptionadvice()--> 例外通知
} finally {
// finallyadvice(); -->最终通知
}
}
return result;
}
}
package cn.itcast.aop;
import java.lang.reflect.Method;
import cn.itcast.service.impl.PersonServiceBean;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGlibProxyFactory implements MethodInterceptor {
private Object targetObject;
public Object createProxyIntance(Object targetObject) {
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer(); // 该类用于生成代理对象
enhancer.setSuperclass(this.targetObject.getClass()); // 设置父类,非final
enhancer.setCallback(this); // 设置回调用对象为本身
return enhancer.create();
}
// 该方法自动调用
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
PersonServiceBean bean = (PersonServiceBean) this.targetObject;
Object result = null;
if (bean.getUser() != null) {
result = methodProxy.invoke(targetObject, args);
}
return result;
}
}
package junit.test;
import org.junit.Test;
import cn.itcast.aop.CGlibProxyFactory;
import cn.itcast.aop.JDKProxyFactory;
import cn.itcast.service.PersonService;
import cn.itcast.service.impl.PersonServiceBean;
public class AOPTest {
@Test
public void jdkProxyTest() {
JDKProxyFactory factory = new JDKProxyFactory();
PersonService service = (PersonService) factory
.createProxyIntance(new PersonServiceBean("xxx"));
service.save("jdkProxyTest");
}
@Test
public void cglibProxyTest() {
CGlibProxyFactory factory = new CGlibProxyFactory();
PersonServiceBean service = (PersonServiceBean) factory
.createProxyIntance(new PersonServiceBean("xxx"));
service.save("cglibProxyTest");
}
}
分享到:
相关推荐
CGLIB 动态代理使用 ASM 字节码工具来生成代理类。CGLIB 动态代理可以代理没有接口的类,這是因为 CGLIB 动态代理可以生成一个原类的子类,然后 override 原类的方法来实现代理。 在 Spring AOP 框架中,默认情况下...
在"通过Configuration文件实现AOP.docx"文档中,可能会详细讲述如何在Spring配置文件中配置AOP代理,包括如何选择使用JDK动态代理还是CGLIB。 总结来说,JDK动态代理简单且高效,适合接口驱动的设计,而CGLIB适用于...
Spring框架是AOP实现的一个典范,它提供了两种主要的动态代理方式:JDK动态代理和CGLib动态代理。 **JDK动态代理**: JDK动态代理基于Java的反射API实现,适用于接口代理。当目标对象实现了至少一个接口时,Spring...
JDK动态代理和CGLIB代理是两种常用的实现方式。 首先,我们来看看JDK动态代理。JDK动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象...
2. **Proxy类**:用于创建动态代理对象,通过`newProxyInstance()`静态方法,传入类加载器、接口数组和InvocationHandler实例来生成代理对象。 3. **实现过程**:首先,你需要定义一个接口,然后创建实现该接口的...
在实际应用中,Spring框架就同时使用了JDK动态代理和CGLIB。当目标对象实现了接口时,Spring会选择JDK动态代理;如果没有实现接口,则使用CGLIB。 总结来说,CGLIB和JDK动态代理都是为了实现运行时的方法拦截,但...
3. 使用Enhancer类,设置拦截器和目标对象的Class,然后通过enhance().create()生成代理对象。 4. 通过代理对象调用目标方法,实际会执行MethodInterceptor的intercept()方法。 **两者区别** 1. 实现方式:JDK代理...
JDK 动态代理是 Java 中的一种动态代理方式,使用 Java 反射机制来生成代理类。JDK 动态代理的优点是可以在运行时生成代理类,无需编写代理类代码。 四、 CGLIB 动态代理 CGLIB 动态代理是另外一种动态代理方式,...
CGLIB示例可能涉及使用Enhancer类来生成代理对象。对于拦截器,可能会展示如何定义和注册拦截器,以及如何构建拦截器链。此外,这些示例还可能包含运行所需的相关jar包,如CGLIB库。 总之,理解和掌握JDK动态代理、...
CGLIB使用ASM库生成代理类的字节码并加载到内存中。当原始类没有接口时,CGLIB比JDK动态代理更适用。 ```java // 引入CGLIB依赖 <groupId>cglib <artifactId>cglib <version>3.3.0 // 使用CGLIB创建代理 ...
否则,使用CGLIB生成一个子类来作为代理。 5. AOP代理的使用:当通过Spring的依赖注入(DI)获取到一个对象时,实际上得到的是一个代理对象。通过这个代理对象调用方法,Spring会自动插入预先定义好的通知逻辑。 ...
Java提供了两种主要的动态代理实现方式:JDK动态代理和CGLIB动态代理。 **JDK动态代理**: JDK动态代理基于接口实现,也就是说,被代理的对象必须实现至少一个接口。代理机制的核心是`java.lang.reflect.Proxy`类和...
1. **Enhancer类**:CGLIB的核心类,用于配置和生成代理对象。你可以设置回调方法、过滤器等,然后通过`enhance()`方法生成代理对象。 2. **MethodInterceptor接口**:类似于JDK的`InvocationHandler`,`...
5. **配置代理**:Spring会根据目标对象是否实现了接口来决定使用JDK动态代理还是CGLIB代理。如果目标对象实现了接口,Spring会选择JDK动态代理。动态代理类会继承自`java.lang.reflect.Proxy`,并实现目标对象的...
- **JDK代理**:JDK动态代理使用反射和InvocationHandler接口生成一个实现了目标接口的新类。在运行时,这个新类的实例作为代理对象,它的方法调用都会转发到InvocationHandler的`invoke()`方法。 - **CGLIB代理**...
在本篇中,我们将深入探讨Spring如何使用动态代理以及其在实际开发中的应用。 动态代理的核心概念是JDK的`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。Proxy类用于创建一个代理对象,...
2. **过程**:CGLIB使用`Enhancer`类作为入口,通过设置回调函数(Callback)和目标对象,生成代理子类。回调函数通常是一个实现了`MethodInterceptor`接口的对象,它在拦截方法调用时执行自定义逻辑。 3. **优点**...
动态代理主要分为两种:JDK代理和CGLIB代理。 **JDK代理**是基于接口的代理,它通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现。当我们的目标对象实现了特定的接口时,我们可以...
本压缩包文件提供了两个示例项目,分别展示了JDK动态代理和CGLib动态代理的实现,帮助我们理解这两种技术的工作原理以及它们生成的class文件结构。 首先,我们来详细了解JDK动态代理。JDK动态代理基于Java的接口...
- Spring支持两种类型的代理:JDK动态代理(如果目标对象实现了接口)和CGLIB代理(如果目标对象没有接口,使用字节码生成技术)。 - 在Spring配置中,可以使用`@Aspect`注解定义切面,`@Before`、`@After`、`@...