反射
1. 在运行时判断任意一个对象所属的类。
2. 在运行时构造任意一个类的对象。
3. 在运行时判断任意一个类所具有的成员变量和方法。
4. 在运行时调用任意一个对象的方法。
在mybatis中
类SqlSessionFactoryBuilder调用build方法
返回DefaultSqlSessionFactory对象(这个对象实现了SqlSessionFactory接口)
类DefaultSqlSessionFactory调用opensession方法
返回DefaultSqlSession对象(实现了SqlSession接口)
DefaultSqlSession调用getMapper方法
返回Configuration的方法getMapper
Configuration调用getMapper
返回MapperRegistry的getMapper
MapperRegistry调用getMapper
返回MapperProxyFactory的newInstance方法
同时将所有Sql读取存入MethodCachenewInstan返回MapperProxy
此时的MapperProxy即为一个代理类
打开MapperProxy可以看到实现了InvocationHandler接口
所有的sql都是通过这条函数执行的
return mapperMethod.execute(sqlSession, args);
打开MapperMethod的execute发现所有的sql实际上是由session执行的
在SpringAOP中
----------
```
//被代理类实现接口
public interface UserService{
public void insert() throws Exception;
}
```
public interface UserServiceImpl{
public void insert() throws Exception;
}
```
被代理类
public class TransactionHandler implements InvocationHandler {
private Object target;
public TransactionHandler(Object target){
super();
this.target = target;
}
//代理类方法执行
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务...");
method.invoke(target);
System.out.println("提交事务...");
return null;
}
}
UserService userService = new UserService();
InvocationHandler handler = new TransactionHandler(userService);
//生成代理类
UserService userServiceProxy =
(UserMgr) Proxy.newProxyInstance(
userMgr.getClass().getClassLoader(), //指定被代理对象的类加载器
userMgr.getClass().getInterfaces(), //指定被代理对象所实现的接口
handler //指定需要调用的InvocationHandler对象
);
userServiceProxy.addUser();
- 通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…);
- 通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…}); - 通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class}); - 通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入
Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));