在阎宏博士的《JAVA与模式》一书中开头是这样描述策略(Strategy)模式的:
策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
Spring 中在实例化对象的时候用到策略模式, 在 SimpleInstantiationStrategy 有使用。
采用实现部分、抽象部分的策略。为了更好的扩展性,把一部分再次抽象,后面可以采用多种实现方式。
public interface InstantiationStrategy {
//默认构造方法
Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) throws BeansException;
//指定构造方法
Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner, Constructor<?> ctor,
Object[] args) throws BeansException;
//指定工厂方法
Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner, Object factoryBean,
Method factoryMethod, Object[] args) throws BeansException;
}
在 SimpleInstantiationStrategy 中对这三个方法做了简单实现。
如果工厂方法实例化直接用反射创建对象,如果是构造方法实例化的则判断是否有 MethodOverrides,如果无 MethodOverrides 也是直接用反射,如果有 MethodOverrides 就需要用 Cglib 实例化对象,SimpleInstantiationStrategy 把通过 Cglib 实例化的任务交给了它的子类 CglibSubclassingInstantiationStrategy。
public class SimpleInstantiationStrategy implements InstantiationStrategy {
// FactoryMethod的ThreadLocal对象,线程所有的变量
private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<Method>();
// 返回当前线程所有的FactoryMethod变量值
public static Method getCurrentlyInvokedFactoryMethod() {
return currentlyInvokedFactoryMethod.get();
}
// 第一种实例化方法,实现部分,部分抽象
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// bd对象定义里,是否包含MethodOverride列表;spring有两个标签参数会产生MethodOverrides ,分别是 lookup-method,replaced-method
// 没有MethodOverride对象,可以直接实例化
if (bd.getMethodOverrides().isEmpty()) {
// 实例化对象的构造方法
Constructor<?> constructorToUse;
// 锁定对象,使获得实例化构造方法线程安全
synchronized (bd.constructorArgumentLock) {
// 查看bd对象里是否含有
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
// 没有就生成
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
// 生成成功后,赋值给bd对象,后面使用
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Exception ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 反射生成对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 有MethodOverride对象,需要使用另一种实现方式,之类实现
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
// 第一种实例化方法的抽象部分
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner) {
throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
}
// 第二种实例化方法,实现部分,抽象部分
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
final Constructor<?> ctor, Object... args) {
// 查看bd对象是否有MethodOverride对象
// 没有MethodOverride,则直接实例化对象
if (bd.getMethodOverrides().isEmpty()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
ReflectionUtils.makeAccessible(ctor);
return null;
}
});
}
// 反射实例化对象
return BeanUtils.instantiateClass(ctor, args);
}
else {
// 有MethodOverride,之类实现实例化方法
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}
// 第二种实例化方法的抽象部分
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner,
Constructor<?> ctor, Object... args) {
throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
}
// 第三种实例化方法,全部实现
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
Object factoryBean, final Method factoryMethod, Object... args) {
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
ReflectionUtils.makeAccessible(factoryMethod);
return null;
}
});
}
else {
ReflectionUtils.makeAccessible(factoryMethod);
}
// currentlyInvokedFactoryMethod,这块暂时还没看到在哪个地方用到了
// 先取出原有的 Method
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
// 设置当前的Method
currentlyInvokedFactoryMethod.set(factoryMethod);
// 使用factoryMethod实例化对象
return factoryMethod.invoke(factoryBean, args);
}
finally {
// 实例化完成,恢复现场
if (priorInvokedFactoryMethod != null) {
currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
}
else {
currentlyInvokedFactoryMethod.remove();
}
}
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(factoryMethod.getReturnType(),
"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(factoryMethod.getReturnType(),
"Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
}
catch (InvocationTargetException ex) {
String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";
if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
"declaring the factory method as static for independence from its containing instance. " + msg;
}
throw new BeanInstantiationException(factoryMethod.getReturnType(), msg, ex.getTargetException());
}
}
}