策略模式作用
将某种可能有多种实现的算法抽象为接口,具体算法通过实现策略接口来实现。这样可以适应多变的场景,通过使用策略接口达到了解耦的目的。
策略接口
// Interface responsible for creating instances corresponding to a root bean definition.
public interface InstantiationStrategy {
}
实例化策略的某个具体实现
public class SimpleInstantiationStrategy implements InstantiationStrategy {
private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<>();
/**
* Return the factory method currently being invoked or {@code null} if none.
* <p>Allows factory method implementations to determine whether the current
* caller is the container itself as opposed to user code.
*/
@Nullable
public static Method getCurrentlyInvokedFactoryMethod() {
return currentlyInvokedFactoryMethod.get();
}
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,@Nullable Object factoryBean, final Method factoryMethod, Object... args) {
try {
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
currentlyInvokedFactoryMethod.set(factoryMethod);
Object result = factoryMethod.invoke(factoryBean, args);
if (result == null) {
result = new NullBean();
}
return result;
}
finally {
// 设计之精髓,在调用实例化时把 factoryMethod 放入 threadLocal 中,如果创建的过程调用 factoryMethod 一次就完成了,那直接把 threadlocal 清楚避免内存泄漏;如果创建的过程中又去调用另一个 factoryMethod 创建实例,那就把在这个 factoryMethod 执行完成后,把 threalocal 恢复为调用之前的样子
if (priorInvokedFactoryMethod != null) {
currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
}
else {
currentlyInvokedFactoryMethod.remove();
}
}
}
catch (IllegalArgumentException ex) {}
catch (IllegalAccessException ex) {}
catch (InvocationTargetException ex) {}
}
}