反射
含义
反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的类的信息,并且可以操作类或对象的内部属性。
作用
- 实例化对象
- 属性注入
- 方法调用
- 获取类信息
例子
代理模式
-
含义:当一个对象不能直接使用,可以在客户端和目标对象直接创建一个中介,这个中介就是代理
-
作用
-
控制访问:在代理中是否可以调用目标对象的方法
-
功能增强:可以在完成目标对象的调用时,附加一些格外的功能,这些格外的功能叫做功能增强
- 缺点:目标类比较多的时候,会产生大量的代理类;当接口改变时,影响目标类
-
-
实现方式
-
静态代理:代理类是手工实现的Java文件,代理的对象是确定的
-
动态代理:利用反射机制,在运行时创建代理类对象,解决了静态代理的痛点:不用创建代理类且可以给不同目标随时创建代理
- java.lang.reflect反射包的三个类
- InvocationHandler
- Method
- Proxy
-
jdk动态代理工具类的实现
-
元素
-
目标类接口(targetInterface)
-
InvocationHandeler的实现类
- invoke()方法完成代理类的功能
- 后续工具类中使用到了函数回调的思想
-
使用Proxy类的静态方法,创建代理对象
-
目标类接口
public interface targetInterface {
int method1(int a,int b);
void method2();
}
目标类
public class target implements targetInterface {
@Override
public int method1(int a, int b) {
System.out.println("I'm method1");
return 0;
}
public void method2(){
System.out.println("I'm method2");
}
}
完善代理的invoke()方法
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before invoking bar()");
Object result = method.invoke(target, args);
System.out.println("after invoking bar()");
return result;
}
}
调用方法
//方法一
targetInterface target = new target();
InvocationHandler invocationHandler = new MyInvocationHandler(target);
targetInterface proxy = (targetInterface) Proxy.newProxyInstance(test.class.getClassLoader(),target.getClass().getInterfaces(),invocationHandler);
proxy.method1(1,1);
proxy.method2();
代理工具类
public class ProxyUtil<T> {
private Callback callback;
private T target;
public ProxyUtil(T target,Callback callback ) {
this.callback = callback;
this.target = target;
}
/**
* 获取代理对象
* @return 代理对象
* @param
*/
public T getProxy(){
//这边不知道如何确定用户创建的实现类,那我们就使用一个匿名的内部实现类来实现
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (callback!=null){
callback.before(method.getName(),args);
}
//result 接收方法返回值
Object result = method.invoke(target, args);
if (callback!=null){
callback.after(method.getName(),args);
}
return result;
}
};
return (T) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),target.getClass().getInterfaces(),invocationHandler);
}
}
//函数反转
interface Callback{
void before(String methodName,Object... args);
void after(String methodName,Object... args);
}
调用工具类
ProxyUtil<targetInterface> targetInterfaceProxyUtil = new ProxyUtil<targetInterface>(target,new Callback(){
@Override
public void before(String methodName, Object... args) {
System.out.println(methodName);
System.out.println("方法前处理");
}
@Override
public void after(String methodName, Object... args) {
System.out.println(methodName);
System.out.println("方法后处理");
}
});
//获取代理对象
targetInterface proxy1 = targetInterfaceProxyUtil.getProxy();
proxy1.method1(1,2);
proxy1.method2();
Spring的Bean配置(扩展点)
-
文件名:spring_config.xml
-
通过main方法:
- 调用ClassPathXmlApplicationContext("spring_config.xml")来加载配置文件
<bean id="apple" class="org.example.factory.Apple" scope="prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
-
Spring框架使用了代理模式来管理Bean的创建和生命周期,并通过反射来辅助实现依赖注入的过程。
-
调用了invoke方法(DelegatingMethodAccessorImpl 类的 invoke)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("sp.xml"); Apple apple = applicationContext.getBean("apple", Apple.class); apple.eat(); -
ApplicationContext使用BeanDefinition来保存对象信息
- Bean的类名
- 作用域
- 构造函数参数
- 属性值
- 依赖关系等
-
Spring容器解析配置文件或者扫描注解的时候,会根据配置信息创建响应的BeanDefinition对象,并保存在内部的数据结构中,通常是一个注册表(类似于一个对象工厂,能够根据Bean的名称或者类型获取对应的Definition对象)
-
在 Spring 的 ApplicationContext 中,
getBean()方法用于从容器中获取指定名称或类型的 Bean 实例
public class DefaultApplicationContext implements ApplicationContext { // ... @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { // 根据名称从容器中获取 BeanDefinition 对象 BeanDefinition beanDefinition = beanRegistry.getBeanDefinition(name); // 根据 BeanDefinition 中的类名使用反射创建对象实例 Class<?> beanClass = beanDefinition.getBeanClass(); T beanInstance; try { beanInstance = requiredType.cast(beanClass.getDeclaredConstructor().newInstance()); } catch (Exception ex) { throw new BeansException("Error creating bean instance", ex); } // 执行依赖注入等初始化操作 // ... return beanInstance; } // ... } -
requiredType.cast()
- Java 中的一个强制类型转换方法,用于将对象转换为指定的类型。
-
getDeclaredConstructor().newInstance()
- 动态地实例化对象
-