我是靠谱客的博主 缓慢外套,最近开发中收集的这篇文章主要介绍【Java】Spring框架的简单模拟实现,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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框架的简单模拟实现所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部