反射机制
1.通过反射可以做什么?
反射机制 java.lang.reflect.* 包下面的类库
我们通过反射机制可以操作一个类的字节码!Test.java --> 编译 javac编译后生成 -> Test.class
通过反射机制可以操作 Test.class字节码
2.类中都有什么?
java.lang.reflect Class Field --》属性
java.lang.reflect Class Method--》方法
java.lang.reflect Class Constructor --》构造方法
public class ReflectTest02 {
public static void main(String[] args) {
Class clazz;
{
try {
clazz = Class.forName("com.wwh.Student");
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method dec : declaredMethods) {
System.out.println(dec);
}
Field[] declaredFields = clazz.getDeclaredFields();
for (Field f:declaredFields){
System.out.println(f);
}
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor:constructors){
System.out.println(constructor);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
3.要想操作一个类的字节码,首先要获取字节码!
如何获取呢? 三种方式获取
Class clazz = Class.forName("com.liushao.reflect.demo01.Student");//第一种Class clazz2 = Student.class;//第二种
Student student = new Student();
Class clazz3 = student.getClass();//第三种
public class ReflectTest01 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class clazz1=Class.forName("com.wwh.Student");
Object o= clazz1.newInstance();//创建这个类对象表示的类的一个新实例。
Student student=new Student();
Class clazz2=student.getClass();
Object o2= clazz2.newInstance();
Class clazz03=Student.class;
Object o3= clazz03.newInstance();
}
}
4.我们获取到一个类之后能做什么?
5.反射的应用场景
Spring--IOC
Spring--AOP
很多框架中 mybatis dubbo rocketmq
6.代理模式
好处:
客户端直接使用的都是代理对象,不知道真实对象是谁,我们的代理对象可以和真实对象之间起到中介的作用.代理对象完全包含真实对象,客户端使用的都是代理对象的方法,和真实对象没有直接关联!
代理模式的职责: 把不是真实对象该做的事情从真实对象上撇开--》 职责分离!6.1分类
静态代理
在程序运行前已经存在代理类的字节码文件,代理对象和真实对象的关系在程序运行前就已经确定了
[代理类和对象由我们进行创建对象]
动态代理
代理类是在程序运行期间由JVM通过反射机制动态生成的,所以不存在代理类字节码文件,动态生成字节码对象,
代理对象和真实对象的关系是在程序运行期间才确定的 (代理类和对象不需要我们进行创建!)6.3 动态代理的实现方式
针对于实现类有接口使用JDK动态代理
针对于实现类没有接口的使用CGLIB动态代理6.4 动态代理的实现机制
参见画图
6.5 静态代理
6.6 动态代理
动态代理和静态代理的区别
静态代理在编译时就已经实现,编译完成后代理类就是一个class文件
动态代理在运行时动态生成的,编译完成后没有实际的class文件,而是在运行时动态生成字节码,并加载JVM中特点:
java.lang.reflect Class Proxypublic static Object newProxyInstance(ClassLoader loader, //指定当前对象使用的类加载器
Class<?>[] interfaces, //目标对象实现的接口类型
InvocationHandler h) //事件处理器
Object // 返回一个指定接口的代理类实例Object invoke(Object proxy,
Method method,
Object[] args)
在代理实例上处理方法调用并返回结果
jarcglib 动态代理
它是一个第三方的类库ASM框架
7.例子
第一个静态代理的例子
public interface IEmployeeService {
public void save(String name,String upwd);
}
public class EmployeeServiceImpl implements IEmployeeService{
@Override
public void save(String name, String upwd) {
System.out.println("保存"+name+"\t"+upwd);
}
}
public class MyTransactionManager {
public void begin(){
System.out.println("开启事务");
}
public void commit(){
System.out.println("提交事务");
}
public void rollback(){
System.out.println("回滚事务");
}
}
public class EmployeeServiceProxy implements IEmployeeService{
private IEmployeeService target;//接口
public void setTarget(IEmployeeService target) {
this.target = target;
}
private MyTransactionManager mt;
public void setMt(MyTransactionManager mt) {
this.mt = mt;
}
@Override
public void save(String name, String upwd) {
try {
mt.begin();
target.save(name, upwd);//调用sava方法。
mt.commit();
}catch (Exception e) {
mt.rollback();
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) {
MyTransactionManager mt = new MyTransactionManager();
EmployeeServiceProxy esp = new EmployeeServiceProxy();
EmployeeServiceImpl esi = new EmployeeServiceImpl();
esp.setTarget(esi);
esp.setMt(mt);
esp.save("wwh","123");
}
}
第二个静态代理的例子:
public interface IUser {
public void save();
}
public class UserDaoImpl implements IUser{
@Override
public void save() {
System.out.println("保存数据");
}
}
public class UserDaoProxy implements IUser{
private IUser target;
public UserDaoProxy(IUser target) {
this.target = target;
}
@Override
public void save() {
//
target.save();
}
}
public class Test {
public static void main(String[] args) {
UserDaoImpl ud=new UserDaoImpl();
UserDaoProxy proxy=new UserDaoProxy(ud);
proxy.save();
}
}
第三个动态的例子:
public interface IUserDao{
void save();
}
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("数据保存");
}
}
public class UserProxyFactory {
private Object target;
public UserProxyFactory(Object target) {
this.target = target;
}
//为目标对象生成代理对象
public Object getProxyInstance(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务");
Object invokeValue = method.invoke(target, args);
return null;
}
});
}
}
public class TestProxy {
public static void main(String[] args) {
IUserDao target=new UserDao();
System.out.println(target.getClass());
IUserDao proxy=(IUserDao)new UserProxyFactory(target).getProxyInstance();
System.out.println(proxy.getClass());
proxy.save();
}
}
第四个例子:拦截器intercept的使用。
普通类,要被代理的对象。
public class UesrDao {
public void save(){
System.out.println("数据保存");
}
}
//代理类
public class ProxyFactory implements MethodInterceptor {
public Object target;//目标对象
public ProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance(){
//工具类
Enhancer en =new Enhancer();
//设置父类
en.setSuperclass(target.getClass());
//设置回调函数
en.setCallback(this);
//创建子类代理对象
return en.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("开启事务");
Object invokeValue = method.invoke(target, objects);
System.out.println("提交事务");
return null;
}
}
//测试类
public class TestProxy {
public static void main(String[] args) {
UserDao target = new UserDao();
System.out.println(target.getClass());
UserDao proxy=(UserDao) new ProxyFactory(target).getProxyInstance();
System.out.println(proxy.getClass());
proxy.save();
}
}
静态代理:静态代理就是,先一个接口,接口里面有一个方法,一个普通类去实现接口。一个代理类,也去继承这个接口,里面去创建普通类对象,含参构造方法,重写接口方法,里面用普通类对象调用接口方法。测试的时候,创建两个实例对象,将普通类放入代理类的构造,接着调用方法。
动态代理:
一种含接口的动态代理:还是一个接口,一个实现接口的普通类,一个不再去实现接口的代理类,这个代理类写一个方法,用到了,Proxy类,Method类,IncocationHandler类。
核心代码:
public Object getProxyInstance(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开启事务"); Object invokeValue = method.invoke(target, args); return null; } }); }
一种不含接口的动态代理:引用资源包cglib。
跟上一个动态代理一样,只是普通类自己写方法体,代理类需要去继承MethodInterceptor类
重写Intercept方法。
然后getProxyInstance方法不一样。
核心代码::
public Object getProxyInstance(){ //工具类 Enhancer en =new Enhancer(); //设置父类 en.setSuperclass(target.getClass()); //设置回调函数 en.setCallback(this); //创建子类代理对象 return en.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("开启事务"); Object invokeValue = method.invoke(target, objects); System.out.println("提交事务"); return null; }