概述
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
首先,Spring框架中实现注入的方式有注解注入和XML配置文件注入。基于注解的配置优点是更短、更简洁,开发效率高,缺点是配置嵌入到各个文件中,比较分散不易于管理。而XML配置优点是配置比较集中、方便管理,缺点是配置冗长、不够简洁。为了达到练习和理解的目的,在此仅通过难度较高的注解注入方式。
之前粗略的实现了基于JDK动态代理和CGLIB动态代理的拦截器,这是Spring框架中AOP的核心,通过此次模拟将拦截器做了改进。而注解是仿照Spring框架中的注解形式(此次模拟涉及的注解):AutoWired、Component、Bean、Qualifier。
(部分解释在代码中已标注)
使用简单工厂模式来处理注解,建立BeanDefinition类和BeanFactory类。
package com.chy.spring.core;
import java.lang.reflect.Method;
// 将类中的方法和拦截器耦合,实现拦截器的添加和方法执行
public class BeanDefinition {
Class<?> klass;
ProxyInvoker proxyInvoker;
boolean done;
private static final ChyProxy CHY_PROXY = new ChyProxy();
BeanDefinition(Class<?> klass) throws Exception {
this.klass = klass;
Object object = klass.newInstance();
Object proxy = CHY_PROXY.getProxy(klass);
this.proxyInvoker = new ProxyInvoker(object, proxy);
this.done = false;
}
BeanDefinition(Object object) {
this.klass = object.getClass();
Object proxy = CHY_PROXY.getProxy(object);
this.proxyInvoker = new ProxyInvoker(object, proxy);
this.done = false;
}
void addIntercepter(Method method, ChyIntercepter chyIntercepter) {
chyIntercepter.addMethod(method);
proxyInvoker.addIntercepter(chyIntercepter);
}
Object invoke(Method method, Object[] args) throws Throwable {
return proxyInvoker.invoke(method, args);
}
boolean isDone() {
return done;
}
Class<?> getKlass() {
return klass;
}
void setKlass(Class<?> klass) {
this.klass = klass;
}
Object getObject() {
return proxyInvoker.getObject();
}
Object getProxy() {
return proxyInvoker.getProxy();
}
@Override
public String toString() {
return klass + ":" + getObject();
}
}
BeanFactory中的基本思路是:将带有Component的类加入Map中,再将带有Bean注解的方法存入方法池中,通过检查AutoWired注解和Qualifier注解完成对成员的赋值注入。
package com.chy.spring.core;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.chy.spring.annotation.AutoWired;
import com.chy.spring.annotation.Bean;
import com.chy.spring.annotation.Component;
import com.chy.spring.annotation.Qualifier;
import com.mec.util.PackageScanner;
import com.mec.util.ValueParser;
public class BeanFactory {
// <类名, BeanDefinition对象>
private static final Map<String, BeanDefinition> beanFactory;
// <类编号, 类名>
private static final Map<String, String> beanIdMap;
// 实例化两个Map,因为存在按类名查找和按可能设定的类的编号查找两种方式
static {
beanFactory = new ConcurrentHashMap<>();
beanIdMap = new ConcurrentHashMap<>();
}
private BeanMethodPool beanMethodPool;
public BeanFactory() {
beanMethodPool = new BeanMethodPool() {
@Override
public void setBeanMethodValue(BeanDefinition beanDefinition) {
try {
setBeanValue(beanDefinition);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Map<String, BeanDefinition> getBeanFactory() {
return beanFactory;
}
};
}
// 设置拦截器
public void setIntercepter(Class<?> klass, Method method, ChyIntercepter chyIntercepter)
throws Exception {
String className = klass.getName();
BeanDefinition beanDefinition = beanFactory.get(className);
if (beanDefinition == null) {
throw new Exception("Bean(" + className + ")不存在!");
}
beanDefinition.addIntercepter(method, chyIntercepter);
}
// 对包扫描,扫描带有Component注解的类,实现BeanFactory的初始化
public void initBeanFactory(String packageName) {
new PackageScanner() {
@Override
public void dealClass(Class<?> klass) {
if (klass.isPrimitive() || klass.isInterface() || klass.isEnum()
|| klass.isAnnotation() || klass.isArray()
|| !klass.isAnnotationPresent(Component.class)) {
return;
}
String klassName = klass.getName();
String beanId = klassName;
Component component = klass.getAnnotation(Component.class);
String id = component.id();
// 判断该类是否有编号
// 有编号则将该类存入beanMap中
if (id.length() > 0) {
beanId = id;
beanIdMap.put(beanId, klassName);
}
try {
BeanDefinition bd = new BeanDefinition(klass);
beanFactory.put(klassName, bd);
collectBeanMethods(klass, bd.getObject());
} catch (Exception e) {
e.printStackTrace();
}
}
}.scannerPackage(packageName);
try {
beanMethodPool.scanPool();
} catch (Exception e) {
e.printStackTrace();
}
}
// 收集带有Bean注解的方法
private void collectBeanMethods(Class<?> klass, Object object) throws Exception {
Method[] methods = klass.getDeclaredMethods();
for (Method method : methods) {
if (!method.isAnnotationPresent(Bean.class)) {
continue;
}
Bean bean = method.getAnnotation(Bean.class);
Class<?> returnType = method.getReturnType();
if (returnType.equals(void.class)) {
throw new Exception("[" + method.getName() + "]不能对void方法加@Bean注解!");
}
String name = bean.name();
BeanMethodDefinition beanMethodDefinition = new BeanMethodDefinition(name, returnType, object, method);
String className = returnType.getName();
if (name.length() > 0) {
beanIdMap.put(name, className);
}
if (beanMethodDefinition.getParameterCount() <= 0) {
Object beanObj = method.invoke(object);
BeanDefinition bd = new BeanDefinition(beanObj);
beanFactory.put(className, bd);
continue;
}
beanMethodPool.addBeanMethod(className, beanMethodDefinition);
}
}
// 给BeanDefinition对象赋值
private void setBeanValue(BeanDefinition bean) throws Exception {
if (bean.isDone()) {
return;
}
// 若该语句放在该方法的结尾,则会造成无穷递归
bean.done = true;
Class<?> klass = bean.getKlass();
Field[] fields = klass.getDeclaredFields();
for (Field field : fields) {
// 遍历寻找含有AutoWired注解的成员
if (!field.isAnnotationPresent(AutoWired.class)) {
continue;
}
// 得到该注解,并取其值
AutoWired autoWired = field.getAnnotation(AutoWired.class);
String value = autoWired.value();
System.out.println(value + "====" + field);
boolean singleton = autoWired.singleton();
setValue(bean, field, value.length() <= 0 ? null : value, singleton);
}
}
// 赋值过程,若成员中存在BeanDefinition类成员,则需要调用setBeanValue方法,对该类内的成员赋值。间接递归!
private void setValue(BeanDefinition bean, Field field,
String value, boolean singleton) throws Exception {
if (value != null) {
setFieldWithValue(bean.getObject(), bean.getKlass(), field, value);
return;
}
// 如果注解的value没有值,则在beanFactory中通过查找该成员的类是否被注入
Class<?> type = field.getType();
System.out.println(type);
BeanDefinition bd = beanFactory.get(type.getName());
if (bd == null) {
BeanDefinition[] beans = searchBeanBySuperType(type);
if (beans.length == 1) {
bd = beans[0];
} else if(beans.length <= 0 || !field.isAnnotationPresent(Qualifier.class)) {
throw new Exception("类" + bean.getKlass() + "中的成员" + field.getName() + "注入失败!");
} else {
Qualifier qualifier = field.getAnnotation(Qualifier.class);
String beanName = qualifier.value();
bd = getBeanDefinition(beanName);
if (bd == null) {
throw new Exception("类" + bean.getKlass() + "的成员" + field.getName() + "注入失败!");
}
}
}
if (!singleton) {
bd = new BeanDefinition(type);
}
if (!bd.isDone()) {
setBeanValue(bd);
System.out.println(bd + "竟然没注入?????");
}
setFieldValue(bean.getObject(), bean.getKlass(), field, bd.getObject());
}
// 按父类或超类中寻找BeanDefinition
private BeanDefinition[] searchBeanBySuperType(Class<?> klass) {
List<BeanDefinition> beanList = new ArrayList<>();
for (BeanDefinition bean : beanFactory.values()) {
Class<?> beanClass = bean.getKlass();
if (klass.isAssignableFrom(beanClass)) {
beanList.add(bean);
}
}
BeanDefinition[] beans = new BeanDefinition[beanList.size()];
// 集合转数组
beanList.toArray(beans);
return beans;
}
// 设置成员的值(值为String类型,转换为Object类型)
private void setFieldWithValue(Object object, Class<?> klass, Field field, String value) throws Exception {
Class<?> type = field.getType();
Object val = ValueParser.stringToObject(type, value);
setFieldValue(object, klass, field, val);
}
// 设置成员的值(值为对象类型)
private void setFieldValue(Object object, Class<?> klass, Field field, Object val) throws Exception {
Class<?> type = field.getType();
String fieldName = field.getName();
// 通过反射机制创建set方法
String methodName = "set" + fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
try {
Method method = klass.getDeclaredMethod(methodName, new Class<?>[] {type});
method.invoke(object, val);
} catch (Exception e) {
// 访问private修饰的成员
field.setAccessible(true);
field.set(object, val);
}
}
// 供内部使用的得到BeanDefinition对象的方法(按对象查找)
static BeanDefinition getBeanDefinition(Object object) {
String beanId = object.getClass().getName();
return getBeanDefinition(beanId);
}
// 供内部使用的得到BeanDefinition对象的方法(按编号查找)
static BeanDefinition getBeanDefinition(String beanId) {
BeanDefinition bean = beanFactory.get(beanId);
if (bean == null) {
String className = beanIdMap.get(beanId);
if (className == null) {
return null;
}
bean = beanFactory.get(className);
}
return bean;
}
// 供外部使用的getBean方法,提供编号或类名即可从BeanFactory中获取
@SuppressWarnings("unchecked")
public <T> T getBean(String beanId) throws Exception {
BeanDefinition bean = beanFactory.get(beanId);
// 懒汉模式
setBeanValue(bean);
return (T) bean.getProxy();
}
@SuppressWarnings("unchecked")
public <T> T getBean(Class<?> klass) throws Exception {
String beanId = klass.getName();
BeanDefinition bean = beanFactory.get(beanId);
if (bean == null) {
throw new Exception("类" + klass.getName() + "不存在");
}
BeanDefinition bd = beanFactory.get(beanId);
// 懒汉模式
setBeanValue(bd);
return (T) bd.getProxy();
}
}
接下来需要对在BeanFactory中的类和方法进行规范处理,包括一个方法池、规范方法和参数。
package com.chy.spring.core;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public abstract class BeanMethodPool {
static final Map<String, BeanMethodDefinition> beanMethodPool
= new ConcurrentHashMap<>();
BeanMethodPool() {
}
void addBeanMethod(String id, BeanMethodDefinition beanMethodDefinition) {
if (beanMethodPool.containsKey(id)) {
return;
}
beanMethodPool.put(id, beanMethodDefinition);
}
// 对池子扫描,考虑线程安全
synchronized void scanPool() throws Exception {
Set<String> ids = beanMethodPool.keySet();
// 执行标志,若有方法执行失败或其他异常,则停止后续方法的执行
boolean hasOne = true;
while (hasOne) {
hasOne = false;
for (String id : ids) {
BeanMethodDefinition beanMethodDefinition = beanMethodPool.get(id);
if (!checkParameter(beanMethodDefinition)) {
continue;
}
// 得到参数,并获取每个参数的值
Object[] args = new Object[beanMethodDefinition.getParameterCount()];
for (int i = 0; i < args.length; i++) {
ChyParameter cp = beanMethodDefinition.parameters.get(i);
args[i] = cp.getValue();
}
// 执行方法
Object beanObject = beanMethodDefinition.getMethod().invoke(beanMethodDefinition.getObject(), args);
// 将方法所在类以及调用该方法的对象加入BeanFactory中
getBeanFactory().put(beanMethodDefinition.getClassName(), new BeanDefinition(beanObject));
// 从方法池中删除该方法
beanMethodPool.remove(id);
hasOne = true;
}
if (beanMethodPool.size() <= 0) {
return;
}
}
}
// 错误处理,包括无法执行的方法
String errorMessage() {
if (beanMethodPool.size() <= 0) {
return null;
}
StringBuffer res = new StringBuffer();
for (String id : beanMethodPool.keySet()) {
BeanMethodDefinition bmd = beanMethodPool.get(id);
Class<?> klass = bmd.getObject().getClass();
res.append("类:" + klass.getName() + "的方法:")
.append(bmd.getMethod().getName() + "无法执行n");
}
return res.toString();
}
// 需要从BeanFactory中获得BeanDefinition,以及设置需要注入的方法
public abstract Map<String, BeanDefinition> getBeanFactory();
public abstract void setBeanMethodValue(BeanDefinition beanDefinition);
// 核对方法参数,从beanMethodDefinition获取
private boolean checkParameter(BeanMethodDefinition beanMethodDefinition) {
for (ChyParameter para : beanMethodDefinition.parameters) {
if (para.value != null) {
continue;
}
Class<?> beanType = para.getType();
String beanName = beanType.getName();
BeanDefinition bd = getBeanFactory().get(beanName);
setBeanMethodValue(bd);
if (bd == null) {
return false;
}
para.value = bd.getObject();
}
return true;
}
}
参数规范:
package com.chy.spring.core;
import java.lang.reflect.Parameter;
// 参数规范
public class ChyParameter {
Class<?> type;
Object value;
ChyParameter(Parameter parameter) {
this.type = parameter.getType();
this.value = null;
}
Class<?> getType() {
return type;
}
Object getValue() {
return value;
}
}
方法的定义和成员规范:
package com.chy.spring.core;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;
public class BeanMethodDefinition {
String name;
String className;
Class<?> type;
Object object;
Method method;
List<ChyParameter> parameters;
BeanMethodDefinition(String name, Class<?> type,
Object object, Method method) {
this.name = name;
this.type = type;
this.className = type.getName();
this.object = object;
this.method = method;
parameters = new ArrayList<>();
Parameter[] parameterList = method.getParameters();
for (Parameter parameter : parameterList) {
// 以ChyParameter对象加入List
parameters.add(new ChyParameter(parameter));
}
}
int getParameterCount() {
return parameters.size();
}
String getName() {
return name;
}
String getClassName() {
return className;
}
Object getObject() {
return object;
}
Method getMethod() {
return method;
}
}
下来是改进后的拦截器:
package com.chy.spring.core;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy {
JDKProxy() {
}
// 类类型参数处理
<T> T getProxy(Class<?> klass) throws Exception {
Object object = klass.newInstance();
return getProxy(object, klass.getClassLoader(), klass.getInterfaces());
}
// 对象类型参数处理
<T> T getProxy(Object object) {
Class<?> klass = object.getClass();
return getProxy(object, klass.getClassLoader(), klass.getInterfaces());
}
@SuppressWarnings("unchecked")
private <T> T getProxy(Object object, ClassLoader classLoader, Class<?>[] interfaces) {
return (T) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 同理CGLIB
BeanDefinition bean = BeanFactory.getBeanDefinition(object);
if (bean == null) {
return method.invoke(object, args);
}
return bean.invoke(method, args);
}
});
}
}
package com.chy.spring.core;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxy {
CglibProxy() {
}
<T> T getProxy(Class<?> klass) throws Exception {
return getProxy(klass, klass.newInstance());
}
<T> T getProxy(Object object) {
return getProxy(object.getClass(), object);
}
@SuppressWarnings("unchecked")
private <T> T getProxy(Class<?> klass, Object object) {
try {
// 通过参数类型的所有构造器,判断是否有可操作的参数
Constructor<?> constructor =
klass.getDeclaredConstructor(new Class<?>[] {});
int modifiers = constructor.getModifiers();
if ((modifiers & Modifier.PRIVATE) != 0) {
return (T) object;
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(klass);
enhancer.setCallback(new MethodInterceptor() {
// 未来执行(无法知道BeanFactory的情况,只能根据当前的object反取BeanFactory中的BeanDefinition)
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// TODO 预留操作,从BeanFactory()中获取ProxyInvoker对象
// return new BeanFactory().getBeanDefinition(klass.getName())
// .proxyInvoker.invoke(object, method, args);
BeanDefinition bean = BeanFactory.getBeanDefinition(object);
if (bean == null) {
return method.invoke(object, args);
}
return bean.invoke(method, args);
}
});
return (T) enhancer.create();
}
}
package com.chy.spring.core;
import java.lang.reflect.Method;
public class ProxyInvoker {
// 对三者的捆绑
// 金初始化一个
Object object;
Object proxy;
IntercepterChain intercepterChain;
ProxyInvoker(Object object, Object proxy) {
this.object = object;
this.proxy = proxy;
intercepterChain = new IntercepterChain(null);
}
public Object getObject() {
return object;
}
public Object getProxy() {
return proxy;
}
// 拦截器的添加采用头插的方式
void addIntercepter(IIntercepter intercepter) {
IntercepterChain newChain = new IntercepterChain(intercepter);
if (intercepterChain.next == null) {
intercepterChain.next = newChain;
} else {
newChain.next = intercepterChain.next;
intercepterChain.next = newChain;
}
}
IntercepterChain getIntercepterChain() {
return intercepterChain;
}
// 将拦截器链和截获的参数一同交给doChain()方法执行
Object invoke(Method method, Object[] args)
throws Throwable {
return intercepterChain.doChain(intercepterChain.next, object, method, args);
}
}
package com.chy.spring.core;
import java.lang.reflect.Method;
public class IntercepterChain {
private IIntercepter intercepter;
// 链域
IntercepterChain next;
boolean beforeOk;
// proxyInvoker和拦截器作为参数传进来,并完成初始化
IntercepterChain(IIntercepter intercepter) {
this.intercepter = intercepter;
this.next = null;
}
IntercepterChain getNext() {
return next;
}
Object doChain(IntercepterChain chain, Object object, Method method, Object[] args)
throws Throwable {
Object result = null;
if (chain != null) {
IIntercepter intercepter = chain.intercepter;
if (intercepter.isMethod(method)) {
if (beforeOk = intercepter.before(args)) {
try {
// 间接递归,再次执行带有拦截器链的invoke方法,走完整个链将退出
result = doChain(chain.next, object, method, args);
// result = proxyInvoker.invoke(chain, method, args);
// 每次退出来的执行后置拦截,若无后置拦截,则结果不变
if (beforeOk) {
result = intercepter.after(result);
}
} catch (Throwable e) {
intercepter.dealException(e);
}
} else {
// 若不是需要拦截的方法,或不进行前置拦截,则直接执行
return result;// = proxyInvoker.invoke(chain, method, args);
}
} else {
result = doChain(chain.next, object, method, args);
}
} else {
result = method.invoke(object, args);
}
return result;
}
}
其中设置了IIntercepter接口,为了达到工具的完整性和实用性,需要一个适配器以及适配器的继承实现类。
package com.chy.spring.core;
import java.lang.reflect.Method;
public interface IIntercepter {
// 前置拦截!
boolean before(Object[] args);
// 后置拦截
Object after(Object result);
// 异常处理
void dealException(Throwable e) throws Throwable;
// 判断是不是需要拦截的方法
public boolean isMethod(Method method);
}
package com.chy.spring.core;
public abstract class ChyIntercepterAdapter implements IIntercepter {
@Override
public boolean before(Object[] args) {
return true;
}
@Override
public Object after(Object result) {
return result;
}
@Override
public void dealException(Throwable e) throws Throwable {
}
//
// @Override
// public boolean isMethod(Method method) {
// return false;
// }
}
package com.chy.spring.core;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public abstract class ChyIntercepter extends ChyIntercepterAdapter{
private List<Method> methods;
public ChyIntercepter() {
methods = new ArrayList<>();
}
void addMethod(Method method) {
methods.add(method);
}
@Override
public boolean isMethod(Method method) {
return methods.contains(method);
}
}
最后
以上就是缓慢外套为你收集整理的【Java】Spring框架的简单模拟实现的全部内容,希望文章能够帮你解决【Java】Spring框架的简单模拟实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复