版权声明:本站所提供的文章资讯、软件资源、素材源码等内容均为本作者提供、网友推荐、互联网整理而来(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考,如有侵犯您的版权,请联系我,本作者将在三个工作日内改正。 https://blog.csdn.net/weixin_42323802/article/details/82468900
(1)动态代理的2个基础条件;
① 必须要有接口
② 必须要有接口的实现类
使用到的 核心类库如下: Proxy 代理类+InvocationHandler还有这个(调用管理者)
(2)另外
代理哪个对象就是被代理的对象执行。
下面提供两种动态代理的写法:常规写法(通用),匿名内部类实现
常规:
package com.company.proxy;
import org.junit.jupiter.api.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @auther SyntacticSugar
* @data 2018/9/6 0006上午 10:54
*/
public class Demo01 {
public static void main(String[] args) {
//
}
}
interface SuperStar {
// 抽象方法 :
void sing(int money);
void liveShow(int money);
void sleep();
}
class LiuYan implements SuperStar {
@Override
public void sing(int money) {
System.out.println("柳岩唱了一首 <<真的真的很爱你>> 歌曲. 挣了 : " + money);
}
@Override
public void liveShow(int money) {
System.out.println("柳岩参加了 <<Running Man>> 节目. 挣了 : " + money);
}
@Override
public void sleep() {
System.out.println("柳岩累了, 休息一下...");
}
}
class FanBingBing implements SuperStar {
@Override
public void sing(int money) {
System.out.println("范冰冰为你唱了一首 <<永远只爱你>> 歌曲. 挣了 : " + money);
}
@Override
public void liveShow(int money) {
System.out.println("范冰冰参加了 <<妈妈去哪里>> 节目. 挣了 : " + money);
}
@Override
public void sleep() {
System.out.println("范冰冰累了, 要休息休息了...");
}
}
class AOPTest {
@Test
public void test1() {
// 1. 创建 `柳岩`
LiuYan ly = new LiuYan();
// 2. 调用方法
ly.sing(10);
ly.sing(100);
ly.sleep();
}
@Test
public void test2() {
// 1. 创建 `范冰冰`
FanBingBing fbb = new FanBingBing();
// 2. 调用方法
fbb.sing(15);
fbb.liveShow(150);
fbb.sleep();
}
/**
* public static Object newProxyInstance(ClassLoader loader,
* Class<?>[] interfaces,
* InvocationHandler h)
*/
@Test
public void test3(){
LiuYan liuYan = new LiuYan();
//创建动态代理
ClassLoader cl = liuYan.getClass().getClassLoader();
Class<?>[] interfaces = liuYan.getClass().getInterfaces();
//匿名内部类实现
InvocationHandler h = getInvocationHandler();//封装
SuperStar superStar = (SuperStar) Proxy.newProxyInstance(cl, interfaces, h);
//调用方法
superStar.liveShow(200);
superStar.sing(15);//15元,和10块进行比较 ,回扣0.3
superStar.sleep();
/**源码:
* @CallerSensitive
* public static Object newProxyInstance(ClassLoader loader,
* Class<?>[] interfaces,
* InvocationHandler h) {
* Objects.requireNonNull(h);
*
* final Class<?> caller = System.getSecurityManager() == null
* ? null
* : Reflection.getCallerClass();
*
* /*
* * Look up or generate the designated proxy class and its constructor.
* *
*Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
*
*return newProxyInstance(caller, cons, h);
*/
}
private InvocationHandler getInvocationHandler() {
return new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//
String methodName = method.getName();
//判断方法名是否一致
if (methodName.equals("sing")) {
//判断参数 int money 是否带足够了 、、sing需要10块钱
if ((int)args[0]<10) {
System.out.println("先生你好,老娘不能为你唱歌");
}
System.out.println("代理抽取了回扣"+0.3*(int)args[0]);
//
}else if (methodName.equals("sleep")){
//无参 直接打印
System.out.println("请带够钱再来消费");
}else if ("liveShow".equals(methodName)){
//设置300元的出场费
if ((int)args[0]<300){
//
System.out.println("不能出场演出");
}
//代理抽取0.3的费用
int money=(int)args[0];
System.out.println("代理抽取了"+0.3*money);
}
return null;//返回过滤的方法
}
};
}
}
匿名内部类:
package com.company.proxy;
import org.junit.jupiter.api.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @auther SyntacticSugar
* @data 2018/9/6 0006下午 7:41
* <p>
* 动态代理
* 代理的哪个对象 就是哪个对象 <被代理的对象被执行调用></>这里是字节码文件对象
* 可以使 new superstar1() 的对象被代理。
*/
public class Demo02 {
@Test
public void test1() {
Liuyan liuyan = new Liuyan();
liuyan.sing(10);
liuyan.liveshow(30);
liuyan.sleep();
}
/**
* 使用动态代理 中间拦截接口的所有的方法
* <p>
* ,源码如下:
* <p>
* public static Object newProxyInstance(ClassLoader loader,
* Class<?>[] interfaces,
* InvocationHandler h) {
* 对返回的 object进行类型的转换 object--》 SuperStar1
*/
@Test
public void test2() {
SuperStar1 star1 = new Liuyan();
//这里调用superstar1 并且使用内部类实现、、
ClassLoader cl = star1.getClass().getClassLoader();//获取classloader
Class<?>[] interfaces = star1.getClass().getInterfaces();//获取interfaces
SuperStar1 o = (SuperStar1) Proxy.newProxyInstance(cl, interfaces, new myInvocationHandler(star1));//获取obj
//
o.sing(20);
o.liveshow(20);
o.sleep();
}
}
class myInvocationHandler implements InvocationHandler {
public static SuperStar1 star1;
public myInvocationHandler(SuperStar1 star1) {
this.star1 = star1;
}
//自定义的myInvocationHandler 实现了 执行调用者
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//pov
String methodName = method.getName();
if (methodName.equals("sing")) {
if ((int) args[0] > 1000) {//大于1000就唱歌,代理拿走固定的200
System.out.println("代理拿走了200柳岩挣了" + ((int) args[0] - 200));
}
System.out.println("兄嘚,你带的钱不够,回去撸代码吧");
} else if (methodName.equals("liveshow")) {
if ((int) args[0] < 2000) {//大于1000就唱歌,代理拿走固定的200
System.out.println("兄嘚,你带的钱不够,回去撸代码吧");
}
int money = (int) args[0] - 500;
System.out.println("代理拿走了500柳岩挣了" + money);
return method.invoke(star1, money);
}
return method.invoke(star1, args);
}
}
interface SuperStar1 {
void sing(int money);
void liveshow(int money);
void sleep();
}
class Liuyan implements SuperStar1 {
@Override
public void sing(int money) {
System.out.println("柳岩唱了一首歌挣了" + money);
}
@Override
public void liveshow(int money) {
System.out.println("柳岩演了场电影挣了" + money);
}
@Override
public void sleep() {
System.out.println("柳岩休息");
}
}
sax解析XML文件:
注意:
①XML文件配置在项目目录下,切记。
②导包 dom4j.jar
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();
}
}
}