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
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