Spring 动态代理
-
(1)JDK的动态代理
》Proxy类的方法
Proxy类的静态方法可以创建代理对象
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
》三个参数
参数1:ClassLoader loader 类加载器 , 用来加载代理对象
参数2:Class<?>[] interfaces 目标类的字节码对象数组. 因为代理的是接口,需要知道接口中所有的方法
参数3:InvocationHandler h 执行句柄, 代理对象处理的核心逻辑就在该接口中 -
案列日志打印
要求在方法执行后打印 :方法名+方法参数+返回值
被代理类和接口
//接口:JDK代理必须提供接口
public interface PersonDao {
public int findPersonByName(String name);
}
//实现类
public class PersonDaoImp implements PersonDao {
@Override
public int findPersonByName(String name) {
int i = 0;
List list = new ArrayList();
list.add("ywf");
list.add("lyf");
list.add("wf");
if (list.indexOf(name) != -1) {
i = 1;
}
return i;
}
}
测试代理
public class DaoAop {
public static void main(String[] args) {
//创建一个实现类在方法织入是使用
PersonDao pd = new PersonDaoImp();
//获取实现类的类加载器
ClassLoader classLoader = PersonDaoImp.class.getClassLoader();
//获取实现类的接口
Class<?>[] interfaces = PersonDaoImp.class.getInterfaces();
//日志类:slf4j+log4j
Logger logger = LoggerFactory.getLogger(PersonDaoImp.class);
//织入处理器,实现方法的增强
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//采用反射来对执行方法,提高通用性
Object returnValue = method.invoke(pd, args);
//在原来方法执行后增强调用日志打印
logger.debug("方法:"+method.getName()+" 参数:"+ Arrays.toString(args)+" 返回值:"+returnValue);
return returnValue;
}
};
//获取代理类
/*三个参数
参数1:ClassLoader loader 类加载器 , 用来加载代理对象
参数2:Class<?>[] interfaces 目标类的字节码对象数组. 因为代理的是接口,需要知道接口中所有的方法
参数3:InvocationHandler h 执行句柄, 代理对象处理的核心逻辑就在该接口中*/
PersonDao personDao = (PersonDao) Proxy.newProxyInstance(classLoader,interfaces,handler);
//调用增强方法
int ywf = personDao.findPersonByName("ywf");
logger.info(ywf+"");
}
}