一、 反射
反射是在程序运行状态下,动态获取类的结构(属性,构造器,方法,注解),动态的创建类对象然后调用类中的属性方法。反射的起源Class,Class中包含类反射要使用的API
获取Class的方法
java
public class Student{
private Integer sId;
private String sName;
private Integer getsId() {
return sId;
}
private void setsId(Integer sId) {
this.sId = sId;
}
private String getsName() {
return sName;
}
private void setsName(String sName) {
this.sName = sName;
}
public Student(Integer sId, String sName) {
this.sId = sId;
this.sName = sName;
}
}
反射的方法:
- 获取类类型 对象
Class<Student> stu = Student.class
0.5)获取类 对象
Student stuObj = stu.new Instance() //默认获取无参构造方法
等价于
Student stuObj = stu.getConstructor().new Instance()
1)获取属性
Field sName = stu.getDeclaredField(''sName'')
sName.setAccessible(true)
Field sId = stu.getDeclaredField("sId")
sId.setAccessible(true)
属性设置值
sName.set(stuObj,''张三'')
sId.set(stuObj,1)
2)获取方法
Method getsId = stu.getMethod("getsId")
getsId.invoke(stuObj)
- 获取构造方法
Constructor c = stu.getConstructor(Integer.class,String.class)
Student s = c.new Instance(1,"张三")
注意事项:
反射获取方法,构造方法,属性方法中 方法名都有加Declared 与 不加Declared。
不加Declared:能够获取父子类中所有public修饰的方法
追加Declared:能够获取当前类中所有修饰符的方法
二)类加载
方法区:放置读取的.class文件
堆区:放置class文件生成的class对象
类加载的过程:
1)转载:查找并加载class文件
2)链接:
验证:验证字节码文件是否符合JVM规范。
准备:为类的静态变量分配内存,初始化化默认值
解析:类中的符号引用转换为直接引用
3)初始化:为类的静态变量赋予正确的初始值
三)Proxy 代理模式
Spring 框架:
IOC控制反转:把项目javabean对象的创建以继生命周期交给spring框架管理
需要使用bean对象时,直接从Spring容器(bean对象的容器)中获取。
利用java的反射,实例化bean对象
AOP面向切面编程:两种动态代理实现
jdk动态代理:实现接口
cglib动态代理:单独的类,没有实现接口
在不修改源代码的情况下扩展功能
静态代理:
目标对象:执行类中方法
代理对象:代理对象中包含目标对象,调用执行对象时可以额外添加功能
注意:静态代理是提前写死的.class文件,并且两个对象类实现同一个接口。跟接口耦合性太高,改动麻烦。
动态代理:
jdk动态代理:
实现InvocationHandler接口,重写invoke方法
1)第一种方式: 直接调用invoke方法
我们在其中内置一个Object对象用来实现对目标方法的调用
javapublic class SqlsessionutilProxyJDK implements InvocationHandler { private Object obj; //代表目标对象 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String name = method.getName(); if ("get".startsWith(name)||"select".startsWith(name)){ Object invoke = method.invoke(obj, args); return invoke; }else { try { SqlSession session = SqlSessionUtil.getSession(); Object invoke = method.invoke(obj, args); session.commit(); return invoke; } catch (Exception e) { SqlSessionUtil.rollbackSession(); throw new RuntimeException(e); } } } }
在Test类中
SqlsessionutilProxyJDK sqlsessionutilProxyJDK = new SqlsessionutilProxyJDK(); Object[] objects = {2,"在职"}; EmpService o =(EmpService) Proxy.newProxyInstance(new EmpServiceImpl().getClass().getClassLoader(), new EmpServiceImpl().getClass().getInterfaces(), new EmpServiceProxyJDK()); Method set = new EmpServiceImpl().getClass().getMethod("set", Integer.class, String.class); sqlsessionutilProxyJDK.setObj(new EmpServiceImpl()); sqlsessionutilProxyJDK.invoke(o, set, objects);
2)简化方式:调用代理对象的相应方法
javapublic class SqlsessionutilProxyJDK implements InvocationHandler { private Object obj; public void setObj(Object obj) { this.obj = obj; } public Object proxyInstance(Object obj){ this.obj = obj; Object o = Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); return o; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String name = method.getName(); if ("get".startsWith(name)||"select".startsWith(name)){ Object invoke = method.invoke(obj, args); return invoke; }else { try { SqlSession session = SqlSessionUtil.getSession(); Object invoke = method.invoke(obj, args); session.commit(); return invoke; } catch (Exception e) { SqlSessionUtil.rollbackSession(); throw new RuntimeException(e); } } } }
在Test类中:
cglib代理:
针对没有接口的类实现代理,实质上是创建这个类的子类,子类对象是代理对象,这个类对象是目标对象
需要在pom文件中引入第三方jar包 。如果在普通的java项目中,还需要有该jar包对应的依赖,但在Maven中会自动添加该jar包的依赖。
java<!-- cglib--> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.12</version> </dependency>
javapublic class CGLIBProxy implements MethodInterceptor { public Object getProxyInstance(Object obj){ Enhancer enhancer= new Enhancer(); enhancer.setSuperclass(obj.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("执行拓展功能"); Object o1 = methodProxy.invokeSuper(o, objects); return o1; } }
在测试类中