版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
接口
package com.shunli.ioc.demo5;
public interface UserDao {
public void save();
public void update();
public void find();
public void delete();
}
实现类
package com.shunli.ioc.demo5;
public class UserDaoImpl implements UserDao{
@Override
public void save() {
System.out.println("save........");
}
@Override
public void update() {
System.out.println("update........");
}
@Override
public void find() {
System.out.println("find........");
}
@Override
public void delete() {
System.out.println("delete........");
}
}
动态代理类
package com.shunli.ioc.demo5;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* 动态代理类
*/
public class MyJdkProxy implements InvocationHandler{
UserDao userDao;
public MyJdkProxy(UserDao userDao) {
this.userDao =userDao;
}
public Object createProxy() {
Object object= Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), this);
return object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("update".equals(method.getName())) {
System.out.println("在调用update前调用....");
}
return method.invoke(userDao, args);
}
}
demo
package com.shunli.ioc.demo5;
import org.junit.Test;
public class Demo {
@Test
public void demo1() {
UserDao userDao = new UserDaoImpl();
UserDao proxy = (UserDao)new MyJdkProxy(userDao).createProxy();
proxy.save();
proxy.update();
proxy.find();
proxy.delete();
}
}
打印结果
Spring在运行期,生成动态代理对象,不需要特殊的编译器
Spring AOP的底层就是通过JDK动态代理或者CGLib动态代理技术为目标Bean执行横向织入
1.若目标对象实现了若干接口,spring使用JDK动态代理
2.若目标对象没有实现任何接口,spring使用CGLib库生成目标对象的子类
程序中应该优先对接口创建代理,便于程序解耦维护,
编辑为final的方法,不能被代理,因为无法进行覆盖
——JDK动态代理,是针对接口生成子类,接口中方法不能使用final修饰,cglib是针对目标类生成子类,因此类或者方不能使用final的
——spring只支持方法连接点,不能供属性连接。