java使用动态代理Proxy

System.out.println(“判断天气是否良好”);

System.out.println(“路况是否良好”);

method.invoke(new GoogleCar(), args);

}else {

//获取接口当中的方法,放到正在执行的方法当中

method.invoke(new GoogleCar(), args);

}

return null;

}

});

car.start();

car.run();

car.stop();

}

}

//也可以实现该接口然后将MyCC传入到第三个参数当中

class MyCC implements InvocationHandler{

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// TODO Auto-generated method stub

return null;

}

}

执行结果:

判断天气是否良好

路况是否良好

控制谷歌的汽车启动

控制谷歌的汽车运行

控制谷歌汽车停止

解析动态代理


TestCar.class.getClassLoader(),

GoogleCar.class.getInterfaces(),

new InvocationHandler()

在这里插入图片描述

上方代码生成TestCar$1.class字节码文件

TestCar$1.class生成上方代码当中的ICar对象的对象car

GoogleCar.class.getInterfaces():TestCar$1.class内放了GoogleCar的一堆方法

动态代理内的参数:

TestCar.class.getClassLoader():

字节码加载器:

jdk有一些程序,专业将各种字节码文件加载到内存当中,这里程序简称为字节码加载器。

如何将字节码文件class文件加载到内存当中?

底层实现的过程,利用IO流这种技术,获取到文件当中的数据,加载到内存当中。

字节码加载器:

在这里插入图片描述

TestCar.class.getClassLoader()将下面获取到的字节码对应的接口加载到本类的字节码当中。

GoogleCar.class.getInterfaces(),告诉虚拟机创建并获取GoogleCar字节码文件当中的所有接口 ,并不能获取其特有的方法。

InvocationHandler()从接口当中获取那个方法,如何获取方法,复制那个方法,并执行新增的方法和特性

Method:正在执行的方法

args:参数

改进上方代码验证各种参数的作用:

public interface ICar {

public String start(int a,int b);

public void run();

public void stop();

}

//相当于mysql的驱动包,是由谷歌汽车的开发人员来实现类

public class GoogleCar implements ICar {

@Override

public String start(int a,int b) {

System.out.println(“控制谷歌的汽车启动”);

//调用谷歌汽车提供的C语言函数

return “start…”+a+" "+b;

}

@Override

public void run() {

System.out.println(“控制谷歌的汽车运行”);

}

@Override

public void stop() {

System.out.println(“控制谷歌汽车停止”);

}

}

package com.itzheng.test06;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.Arrays;

public class TestCar {

public static void main(String[] args) {

// TestCar.class.getClassLoader()将下面获取到的字节码对应的接口加载到本类的字节码当中

// GoogleCar.class.getInterfaces(),告诉虚拟机创建并获取GoogleCar字节码文件当中的所有接口

// new InvocationHandler()从接口当中获取那个方法,如何获取方法,复制那个方法,并执行新增的方法和特性

// 最后通过上方一系列操作创建了一个对象ICar car = (ICar)需要强转

ICar car = (ICar) Proxy.newProxyInstance(TestCar.class.getClassLoader(), GoogleCar.class.getInterfaces(),

new InvocationHandler() {

//method代表正在执行的方法

//args:代表正在执行的方法的参数

//Object:代表方法执行完毕之后的返回值

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// 经过测试得知:method代表当前正在执行每个方法

// System.out.println(method.getName());//获取到是是字节码文件GoogleCar当中的所有方法名称

// 执行当前的方法

// method.invoke(new GoogleCar(), args);

// 代表每个方法执行完毕之后返回的对象

Object obj = null;

if (method.getName().equalsIgnoreCase(“start”)) {// equalsIgnoreCase忽略大小写比较

// 执行当前method对应的方法

System.out.println(“判断天气是否良好”);

// 打印args里面的内容

System.out.println(Arrays.toString(args));

System.out.println(“路况是否良好”);

obj = method.invoke(new GoogleCar(), args);

} else {

// 获取接口当中的方法

obj = method.invoke(new GoogleCar(), args);

}

return obj;

}

});

String cc = car.start(1, 4);

System.out.println(cc);

car.run();

car.stop();

}

}

//也可以实现该接口然后将MyCC传入到第三个参数当中

class MyCC implements InvocationHandler {

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// TODO Auto-generated method stub

return null;

}

}

执行结果

判断天气是否良好

[1, 4]

路况是否良好

控制谷歌的汽车启动

start…1 4

控制谷歌的汽车运行

控制谷歌汽车停止

字节码加载器:3种

1、系统引导加载器:.class.getClassLoader() java当中不存在由其他语言来实现的

public class TestClassLoader {

public static void main(String[] args) {

//系统引导的类加载器

//获取String类的加载器

ClassLoader classLoader = String.class.getClassLoader();//String类的字节码加载器

System.out.println(classLoader);

//由于String.class,int.class等字节码文件需要频繁的被加载到内存速度必须块,底层用其他语言来实现

}

}

在这里插入图片描述

2、ExtClassLoader扩展类加载器

public class TestClassLoader {

public static void main(String[] args) {

//获取ext(extendtion)包下的某个类下的字节码加载器

//ExtClassLoader扩展类加载器

ClassLoader classLoader2 = sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader();

System.out.println(classLoader2);

}

}

输出结果:

在这里插入图片描述

3、应用类加载器 AppClassLoader应用类内存当中实际存在的类

应用类:一般实现的所有类都是属于应用类(自己创建的类)

public class TestClassLoader {

public static void main(String[] args) {

//应用类:一般实现的所有类都是属于应用类(自己创建的类)

//获取应用类加载器 AppClassLoader

ClassLoader classLoader3 = TestClassLoader.class.getClassLoader();

System.out.println(classLoader3);

}

}

在这里插入图片描述

解决网站动态代理编码的问题

========================================================================

案例:动态代理解决全站乱码问题

步骤:

1、new DynamicWeb Progect > index.html

Insert title here

post方式提交的中文

User:
<input

type=“submit” />

get方式提交的中文

User:
<input

type=“submit” />

2、建立ServletDemo

public class ServletDemo extends HttpServlet {

private static final long serialVersionUID = 1L;

public ServletDemo() {

super();

}

protected void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

String um = request.getParameter(“username”);

System.out.println(request.hashCode()+" :"+um);

}

protected void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

String um = request.getParameter(“username”);

System.out.println(request.hashCode()+" :"+um);

}

}

无论是在post/get方法,执行以下语句不存在中文乱码问题

String um = request.getParameter(“username”);

System.out.println(um);

3、在过滤器当中为request上的getParameter();进行增强

思路:

判断当前的请求是get/post request.getMethod();

request.getMethod();返回的如果是post,设置一句话:request.setCharacterEncoding("utf-8");//放行

如果是get,调用原先的String v = request.getParameter(name);

将v进行转码,放行

案例的实现

在这里插入图片描述

next > /EncodingFilter > /*

在这里插入图片描述

在这里插入图片描述

package cn.itcast.test00;

import java.io.IOException;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

public class EncodingFilter implements Filter {

public EncodingFilter() {

}

public void destroy() {

}

public void init(FilterConfig fConfig) throws ServletException {

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

//将request转换为HttpServletRequest

final HttpServletRequest req = (HttpServletRequest)request;

//让jdk在内存当中生成一个代理对象:增强了req对象上的getParmeter(name);API

HttpServletRequest myReq = (HttpServletRequest)Proxy.newProxyInstance(EncodingFilter.class.getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// TODO Auto-generated method stub

Object obj = null;

if(method.getName().equalsIgnoreCase(“getParameter”)) {

总结

如果你选择了IT行业并坚定的走下去,这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了

《Java中高级核心知识全面解析》

小米商场项目实战,别再担心面试没有实战项目:

加入社区:https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0
ttpServletRequest myReq = (HttpServletRequest)Proxy.newProxyInstance(EncodingFilter.class.getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// TODO Auto-generated method stub

Object obj = null;

if(method.getName().equalsIgnoreCase(“getParameter”)) {

总结

如果你选择了IT行业并坚定的走下去,这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了

《Java中高级核心知识全面解析》

[外链图片转存中…(img-n3E977JX-1725656508874)]

小米商场项目实战,别再担心面试没有实战项目:

[外链图片转存中…(img-LoGh2Bpj-1725656508875)]

加入社区:https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值