这里我们就需要用到cglib-nodep-2.1_3.jar这个包
下面代码是演示的是一个用户权限判断,并赋予这个用户相应的操作。这里我做的是这样的用户权限设置:只要用户名不为空,那么就赋予它操作目标类中的所有方法的权利
代码一:
package cn.itcast.service;
public interface IPersonService {
public void save(String name);
}
代码二 CGlibProxyFactory.java和JDKProxyFactory.java
package cn.itcast.service.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());//CGlib是集成目标类,然后覆盖目标类中的非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){
//advice -->AOP术语:前置通知
try {
result = methodProxy.invoke(targetObject, args);
//afteradvice-->AOP术语:后置通知
} catch (Exception e) {
//Exceptionadvice-->AOP术语:例外通知
}finally{
//finallyadvice-->AOP术语:最终通知
}
}
return result;
}
}
package cn.itcast.service.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import cn.itcast.service.impl.personServiceBean2;
public class JDKProxyFactory implements InvocationHandler{
private Object targetObject;
public Object createProxyIntance(Object targetObject){
this.targetObject =targetObject;
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader()
, this.targetObject.getClass().getInterfaces(), this);
}
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
personServiceBean2 bean =(personServiceBean2) this.targetObject;
Object result = null;
if(bean.getUser()!=null){
result = arg1.invoke(targetObject, arg2);
}
return result;
}
}
代码三:personServiceBean.java和personServiceBean2.java
package cn.itcast.service.impl;
import cn.itcast.service.IPersonService;
public class personServiceBean {
private String user ;
public String getUser() {
return user;
}
public personServiceBean() {
}
public personServiceBean(String user) {
this.user = user;
}
public String getPersonName(Integer personId) {
return "postino";
}
public void save(String name) {
System.out.println("这是save方法");
}
}
package cn.itcast.service.impl;
import cn.itcast.service.IPersonService;
public class personServiceBean2 implements IPersonService {
private String user ;
public String getUser() {
return user;
}
public personServiceBean2() {
}
public personServiceBean2(String user) {
this.user = user;
}
public String getPersonName(Integer personId) {
return "postino";
}
public void save(String name) {
System.out.println("这是save方法");
}
public void update(String name, Integer personId) {
System.out.println("这是update方法");
}
}
测试类:AOPTest.java
package junit.test;
import static org.junit.Assert.*;
import org.junit.BeforeClass;
import org.junit.Test;
import cn.itcast.service.aop.CGlibProxyFactory;
import cn.itcast.service.aop.JDKProxyFactory;
import cn.itcast.service.impl.personServiceBean;
import cn.itcast.service.impl.personServiceBean2;
import cn.itcast.service.IPersonService;
public class AOPTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test public void proxyTest(){
JDKProxyFactory jdkpf = new JDKProxyFactory();
IPersonService ipersonService = (IPersonService)jdkpf.createProxyIntance(new personServiceBean2(""));
ipersonService.save("");
}
@Test public void proxyTest2(){
CGlibProxyFactory jdkpf = new CGlibProxyFactory();
personServiceBean service = (personServiceBean)jdkpf.createProxyIntance(new personServiceBean(""));
service.save("");
}
}
学习总结:
1:JDKProxy拦截是,通过新建一个Proxy对象来实现的,里面传入三个参数,一个目标类的类加载器,一个目标类实现了的接口,一个目标类对象Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader() , this.targetObject.getClass().getInterfaces(), this);
2:CGlib是通过定义Enhancer类的对象,然后覆盖目标类的非final方法实现的集成,在通过回调
3:如果是用JDKProxy实现拦截,那么目标类必须是面向接口编程。而CGlib则不需要
分享到:
相关推荐
Spring 2.5 AOP(面向切面编程)是Java应用程序中的一个重要概念,它允许开发者在不修改原有代码的情况下插入新的行为或监控。这个例子旨在帮助我们理解和应用Spring框架的AOP特性。以下是对该主题的详细解释: 一...
本篇将深入探讨如何使用JDK的动态代理和CGLIB库来实现Spring中的AOP功能。 首先,我们来看JDK中的Proxy技术。JDK Proxy是Java提供的一种动态代理机制,它允许我们在运行时创建一个实现了特定接口的新类。这个新类...
- **动态代理**:Spring AOP主要使用JDK动态代理和CGLIB实现。如果目标类实现了接口,使用JDK动态代理;否则,使用CGLIB生成子类作为代理。 - **切点(Pointcut)**:定义连接点的筛选规则,通过表达式或注解来...
5. **配置代理**:Spring会根据目标对象是否实现了接口来决定使用JDK动态代理还是CGLIB代理。如果目标对象实现了接口,Spring会选择JDK动态代理。动态代理类会继承自`java.lang.reflect.Proxy`,并实现目标对象的...
在Spring AOP(面向切面编程)中,CGLIB是一个重要的动态代理库,它用于在运行时创建子类以实现对目标对象的代理。CGLIB是针对那些不支持接口代理(例如Java中的final类)的情况而设计的。下面我们将深入探讨Spring ...
1. JDK动态代理:当目标类实现了至少一个接口时,Spring会使用java.lang.reflect.Proxy创建一个代理对象,该代理对象在调用接口方法时执行通知。这是基于接口的代理,因此,如果目标类没有实现任何接口,JDK动态代理...
4. **丰富的切入点表达式语言**:Spring AOP支持使用SpEL(Spring Expression Language)来定义复杂的切入点表达式,这让开发者能够更加灵活地控制通知的触发条件。 #### 四、Spring AOP的实现示例 接下来,我们...
在Spring中,AOP主要通过两种动态代理技术实现:JDK动态代理和CGLIB动态代理。 首先,让我们详细了解一下JDK动态代理。JDK动态代理基于Java的接口实现,它适用于目标对象实现了至少一个接口的情况。在运行时,JDK...
在本篇Spring学习笔记中,我们将探讨如何使用CGLIB库来实现AOP功能。 CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,它被广泛用于动态代理和运行时织入AOP切面。在Spring中,如果目标类没有...
静态代理--不适合企业开发,适合初学者理解代理。 jdk动态代理--适合企业级开发,但是它要求必须面向接口编程,假如目标类没有实现接口...spring 的AOP功能中 会根据目标类是否实现了接口来判断使用 jdk Proxy还是cglib
- **注解配置**:Spring 2.5引入了基于注解的AOP,可以直接在切面类上使用@Aspect,@Before、@After、@Around等注解定义通知,@Pointcut定义切点。 4. **切点表达式** - 切点表达式是用于匹配连接点的语句,如`...
- **代理(Proxy)**:Spring创建的用于拦截目标对象调用并插入通知的对象。 3. **Spring AOP的实现方式**: - **基于XML的配置**:在Spring的配置文件中定义切面、通知、切点等。 - **基于注解的配置**:使用...
4. 代理的创建:Spring根据目标对象是否实现接口来决定使用JDK动态代理还是CGLIB。如果目标对象实现了接口,Spring将使用JDK动态代理;否则,使用CGLIB生成一个子类来作为代理。 5. AOP代理的使用:当通过Spring的...
在Spring AOP中,当目标对象实现了至少一个接口时,Spring会使用JDK的动态代理来创建代理对象。这是因为JDK的动态代理只适用于实现了接口的类,它通过生成一个与目标类接口相同的新类来实现代理。这个新类在运行时被...
本文将深入探讨如何使用Spring的IOC和DI特性,结合动态代理(Dynamic Proxy)来实现一种类似AOP(面向切面编程)的功能,以达到在不修改原有代码的情况下增强或拦截方法调用的目的。 **一、Spring IOC(控制反转)*...
1. **JDK动态代理**:Spring在没有CGLIB库的情况下,会使用Java的反射API创建动态代理。动态代理类会实现目标接口,并在调用接口方法时插入通知。因此,使用JDK动态代理的目标类必须实现至少一个接口。 2. **CGLIB...
- 当目标对象实现了至少一个接口时,Spring会使用JDK的java.lang.reflect.Proxy类创建一个代理对象。 - 代理对象在调用实际方法前后,会插入相应的通知代码,从而实现AOP功能。 - **CGLIB代理**: - 如果目标...
JDK和CGLIB是Java中实现动态代理的两种主要方式,它们在Spring框架中扮演着关键角色,尤其是在AOP(面向切面编程)中。 1. **JDK动态代理**: JDK动态代理基于Java的接口机制实现,因此,要使用JDK动态代理,被...
7. 代理(Proxy):Spring创建的用于包含切面逻辑的对象,它可以是JDK动态代理或CGLIB代理。 接下来,我们将探讨如何使用注解定义切面: 1. @Aspect:这个注解标记一个类作为切面。在切面类中,我们可以定义切入点...
Spring框架中的AOP模块使用了动态代理来实现AOP概念。Spring AOP允许开发者定义切面,并在这些切面中指定拦截的方法。Spring AOP支持不同的代理策略,包括JDK动态代理和CGLIB代理。如果被代理的类没有实现接口,...