声明,使用 JDK8 ,idea2018.2 ,maven3.5.4;
2018.11.12今天翻开自己增写的动态代理,发现乱的一批,从新梳理了动态代理;
12/9 再次整理;
动态代理和静态代理有什么区别?
静态代理仅仅代理一个类,而动态代理代理的是接口下的多个实现类;
静态代理事先知道代理的具体的哪一个类,动态代理却只能在运行时才知道自己代理的是哪一个具体的类;
1、动态代理常见有2种、基于JDK和第三方依赖CgLib这两种方式实现:
一、基于 java 的动态代理:
JDK动态代理实现 InvacationHandler 接口中的 invoke 方法,才能够完成动态代理,其代理的是接口,业务类 通过Proxy中的newProxyInstance 获取代理的对象;如下示例、
// 属性注入
@Autowired
private CustomerDao customerDao;
@Test
public void test01() {
CustomerDao proxyInstance = (CustomerDao) Proxy.newProxyInstance(customerDao.getClass().getClassLoader(), customerDao.getClass().getInterfaces(), new InvocationHandler() {
/**
* @param proxy 代理对象
* @param method 目标方法
* @param args 目标参数列表
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 可以在代理方法执行 之前执行其他的方法、
System.out.println(" 代理对象执行之前插入该方法执行 ");
Object invoke = method.invoke(customerDao, args);
return invoke;
}
});
// 执行代理方法
proxyInstance.save();
}
二、基于 cglib的动态代理:
cglib 动态代理代理的是类,通过派生的子类实现代理、解决了没有实现接口情况下,就可以完成动态代理;
试试
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.8</version>
</dependency>
测试代理:
@Test
public void test02(){
// 创建cglib核心对象
Enhancer enhancer = new Enhancer();
LinkManDao linkManDao = new LinkManDao();//LinkManDao 是一个实体类
// 设置 父类 、回调
enhancer.setSuperclass(linkManDao.getClass());
enhancer.setCallback(new MethodInterceptor() {
/**
* @param o 代理对象
* @param method 目标方法
* @param objects 参数
* @param methodProxy 代理方法
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("开始执行代理");
/** Object result = method.invoke(linkManDao, objects);
Object result = methodProxy.invokeSuper(o, objects);
* 以上都属于动态代理的访问时执行 method
*/
// Object result = method.invoke(linkManDao, objects);
Object result = methodProxy.invokeSuper(o, objects);
return result;
}
});
// 代理对象执行 方法
LinkManDao o = (LinkManDao) enhancer.create();
o.save();
}
2、SAX解析XML、是基于社区的一种解析方式:
1、XML文件配置在项目目录下,切记;
<!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
package com.company.schema;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.util.List;
/**
* @auther SyntacticSugar
* @data 2018/9/6 0006下午 9:01
* <p>
* 使用dom4j 解析xml 文件 、、使用到saxReader
* analyse :
* 获取dom ,获取根标签 ,获取根标签下的 子标签child
*获取子标签下的子标签获取Att 或者文本 或者 node
*/
public class Demo {
//
public static void main(String[] args) {
try {
SAXReader saxReader = new SAXReader();
Document dom = saxReader.read("book.xml");
Element rootElement = dom.getRootElement();//获取根标签
List<Element> elements = rootElement.elements();
//遍历元素
for (Element element : elements) {
String text = element.element("name").getText();
String name = element.element("name").getName();
System.out.println(name+"="+text);
}
//
} catch (Exception e) {
e.printStackTrace();
}
}
}