项目目的

在理解 Spring 系统结构、实现原理的基础上,自己动手写一个实现Spring核心功能的框架,以达到学习的目的。

项目入口

项目的入口为DispatcherSerlvet的init()方法中,在Servlet 的 init 方法初始化了IOC容器和Spring MVC所依赖的组件

项目搭建

本篇博客代码地址:https://github.com/jinzzzzz/spring-demo

用户配置

application.properties配置

application.properties作为配置文件,配置所需要的属性,配置如下:

1
scanPackage=top.jinjinz.spring

web.xml 配置

配置自定义Servlet DispatcherServlet及设置匹配请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Web Application</display-name>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>top.jinjinz.spring.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

项目配置

build.gradle配置

build.gradle配置相关的jar包依赖,目前只依赖了servlet api。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
subprojects {
apply plugin: 'java'

group 'spring-demo'


repositories {
mavenCentral()
}

dependencies {
compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
}
}

项目模块

项目名 项目描述
spring-core IOC容器/依赖注入
spring-webmvc web框架,基于Servlet
spring-aop AOP框架
spring-test 测试项目

项目设计

spring-aop

实现切面功能,判断加上注解的类注册切面方法。

注解定义

定义aop相关注解@After@Aspect@Before

1
2
3
4
5
6
7
8
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface After {

String value();

String argNames() default "";
}
1
2
3
4
5
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Aspect {
public String value() default "";
}
1
2
3
4
5
6
7
8
9
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Before {

String value();

String argNames() default "";

}

接口定义

Advice

1
2
3
4
5
6
7
8
9
package top.jinjinz.spring.aop;

/**
* Advice标签接口
* @author jinjin
* @date 2019-04-22
*/
public interface Advice {
}

AopProxy

1
2
3
4
5
6
7
8
9
10
11
12
13
package top.jinjinz.spring.aop;

/**
* AOP代理的接口
* @author jinjin
* @date 2019-04-18
*/
public interface AopProxy {

Object getProxy();

Object getProxy(ClassLoader classLoader);
}

Joinpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package top.jinjinz.spring.aop.intercept;


/**
* 连接点
* @author jinjin
* @date 2019-04-18
*/
public interface Joinpoint {

Object proceed() throws Throwable;

Object getThis();
}

MethodInterceptor

1
2
3
4
5
6
7
8
9
10
package top.jinjinz.spring.aop.intercept;

/**
* 方法调用过程中调用
* @author jinjin
* @date 2019-04-18
*/
public interface MethodInterceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}

MethodInvocation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package top.jinjinz.spring.aop.intercept;

import java.lang.reflect.Method;

/**
* 方法拦截
* @author jinjin
* @date 2019-04-18
*/
public interface MethodInvocation extends Joinpoint{

Method getMethod();

Object[] getArguments();
}

功能实现

AdvisedSupport

保存类方法执行时关联的调用链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package top.jinjinz.spring.aop;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
* AOP代理配置管理器的基类
* @author jinjin
* @date 2019-04-18
*/
public class AdvisedSupport {

private Class<?> targetClass;

private Object target;

private Pattern pointCutClassPattern;

/** 缓存方法为键,调用链列表为值 */
private transient Map<Method, List<Object>> methodCache;

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Method method,Class<?> targetClass)
throws Exception {
List<Object> cached = this.methodCache.get(method);
if (cached == null) {
Method m =
targetClass.getMethod(method.getName(),method.getParameterTypes());
cached = methodCache.get(m);
this.methodCache.put(method, cached);
}
return cached;
}

public Class<?> getTargetClass() {
return targetClass;
}

public void setTargetClass(Class<?> targetClass) {
this.targetClass = targetClass;
}

public Object getTarget() {
return target;
}

public void setTarget(Object target) {
this.target = target;
}

public Pattern getPointCutClassPattern() {
return pointCutClassPattern;
}

public void setPointCutClassPattern(Pattern pointCutClassPattern) {
this.pointCutClassPattern = pointCutClassPattern;
}

public Map<Method, List<Object>> getMethodCache() {
return methodCache;
}

public void setMethodCache(Map<Method, List<Object>> methodCache) {
this.methodCache = methodCache;
}
}

JdkDynamicAopProxy

使用jdk动态代理,执行方法时,执行方法调用链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package top.jinjinz.spring.aop;

import top.jinjinz.spring.aop.intercept.MethodInvocation;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
* JDK动态代理实现{@link AopProxy}
* @author jinjin
* @date 2019-04-18
*/
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {

private final AdvisedSupport advised;

public JdkDynamicAopProxy(AdvisedSupport config) throws Exception {
this.advised = config;
}

@Override
public Object getProxy() {
return getProxy(this.advised.getTargetClass().getClassLoader());
}

@Override
public Object getProxy(ClassLoader classLoader) {
return Proxy.newProxyInstance(
classLoader,this.advised.getTargetClass().getInterfaces(),this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(
method,this.advised.getTargetClass());
//如果没有可以应用到此方法的通知(Interceptor),直接反射调用
if(null==chain){
return method.invoke(proxy, args);
}
MethodInvocation invocation = new ReflectiveMethodInvocation(
proxy,advised.getTarget(),method,args,this.advised.getTargetClass(),chain);
return invocation.proceed();
}
}

ProxyFactory

生成代理对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package top.jinjinz.spring.aop;

import java.lang.reflect.Proxy;

/**
* 用于AOP代理的工厂,用于编程使用,而不是通过声明性
* @author jinjin
* @date 2019-04-18
*/
public class ProxyFactory extends AdvisedSupport{


public Object getProxy() throws Exception {
return createAopProxy().getProxy();
}

public Object getProxy(ClassLoader classLoader) throws Exception{
return createAopProxy().getProxy(classLoader);
}

private synchronized AopProxy createAopProxy() throws Exception{
Class<?> targetClass = getTargetClass();
if (targetClass == null) {
throw new Exception("没有代理目标类");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(this);
}
//todo 没有继承接口的类需要cglib代理
//return new ObjenesisCglibAopProxy(config);
return new JdkDynamicAopProxy(this);
}


}

ReflectiveMethodInvocation

执行方法调用链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package top.jinjinz.spring.aop;

import top.jinjinz.spring.aop.intercept.MethodInterceptor;
import top.jinjinz.spring.aop.intercept.MethodInvocation;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
* aop实现类
* @author jinjin
* @date 2019-04-18
*/
public class ReflectiveMethodInvocation implements MethodInvocation {

protected final Object proxy;

protected final Object target;

protected final Method method;

protected Object[] arguments = new Object[0];

private final Class<?> targetClass;

private Map<String, Object> userAttributes;

protected final List<?> interceptorsAndDynamicMethodMatchers;

//定义一个索引,从-1开始来记录当前拦截器执行的位置
private int currentInterceptorIndex = -1;

public ReflectiveMethodInvocation(
Object proxy,Object target, Method method,Object[] arguments,
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {

this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
this.method = method;
this.arguments = arguments;
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}

@Override
public Method getMethod() {
return this.method;
}

@Override
public Object[] getArguments() {
return this.arguments;
}

@Override
public Object proceed() throws Throwable {
//如果Interceptor执行完了,则执行joinPoint
if (this.currentInterceptorIndex ==
this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.method.invoke(this.target,this.arguments);
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(
++this.currentInterceptorIndex);
//动态匹配joinPoint
if (interceptorOrInterceptionAdvice instanceof MethodInterceptor) {
MethodInterceptor mi = (MethodInterceptor) interceptorOrInterceptionAdvice;
return mi.invoke(this);
} else {
//动态匹配失败时,略过当前Intercetpor,调用下一个Interceptor
return proceed();
}
}

@Override
public Object getThis() {
return this.target;
}
}

AutoProxyCreator

实现BeanPostProcessor接口,在初始化bean时调用,此时创建代理对象并加入调用方法链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package top.jinjinz.spring.aop.autoproxy;

import top.jinjinz.spring.aop.AdvisedSupport;
import top.jinjinz.spring.aop.ProxyFactory;
import top.jinjinz.spring.aop.adapter.AfterReturningAdviceInterceptor;
import top.jinjinz.spring.aop.adapter.MethodBeforeAdviceInterceptor;
import top.jinjinz.spring.aop.annotation.After;
import top.jinjinz.spring.aop.annotation.AfterThrowing;
import top.jinjinz.spring.aop.annotation.AopProxyUtils;
import top.jinjinz.spring.aop.annotation.Before;
import top.jinjinz.spring.aop.aspectj.AspectJAdvice;
import top.jinjinz.spring.beans.factory.BeanFactory;
import top.jinjinz.spring.beans.factory.config.BeanPostProcessor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* 自动创建代理
* @author jinjin
* @date 2019-04-18
*/
public class AutoProxyCreator implements BeanPostProcessor {

private final Map<String,List<AspectJAdvice>> aspectMethods;

private final List<String> patterns;

public AutoProxyCreator(Map<String, List<AspectJAdvice>> aspectMethods,
List<String> patterns) {
this.aspectMethods = aspectMethods;
this.patterns = patterns;
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName,
BeanFactory beanFactory)
throws Exception {
if (bean != null) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(bean);
proxyFactory.setTargetClass(bean.getClass());
proxyFactory.setMethodCache(
getMethodCathe(proxyFactory,beanFactory,Before.class));
return proxyFactory.getProxy();
}
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName,
BeanFactory beanFactory)
throws Exception {
if (bean != null) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(bean);
proxyFactory.setTargetClass(bean.getClass());
proxyFactory.setMethodCache(
getMethodCathe(proxyFactory,beanFactory,After.class));
return proxyFactory.getProxy();
}
return bean;
}

private List<Object> getAdvices(
String p,BeanFactory beanFactory,Class<? extends Annotation> annotationClass)
throws Exception{
List<Object> advices = new ArrayList<>();
List<AspectJAdvice> aspectJAdviceList = aspectMethods.get(p);
for (AspectJAdvice aspectJAdvice:aspectJAdviceList) {
//注入
if(aspectJAdvice.getAspectTarget() instanceof String){
aspectJAdvice.setAspectTarget(
beanFactory.getBean((String)aspectJAdvice.getAspectTarget()));
}
if(aspectJAdvice.getAspectMethod().isAnnotationPresent(Before.class)){
advices.add(new MethodBeforeAdviceInterceptor(aspectJAdvice));
}else if(aspectJAdvice.getAspectMethod().isAnnotationPresent(After.class)){
advices.add(new AfterReturningAdviceInterceptor(aspectJAdvice));
}
}
return advices;
}

private Map<Method, List<Object>> getMethodCathe(
AdvisedSupport advisedSupport,BeanFactory beanFactory,
Class<? extends Annotation> annotationClass) throws Exception{
Map<Method, List<Object>> methodCache = new HashMap<>();
Method[] methods=advisedSupport.getTargetClass().getMethods();
List<Object> advices;
Matcher matcher;
String methodString;
Pattern pattern;
for (Method method:methods) {
methodString = method.toString();
if(methodString.contains("throws")){
methodString =
methodString.substring(0,methodString.lastIndexOf("throws")).trim();
}
//判断所有的Aspect中的方法上的正则查看是否匹配
for (String p:patterns){
pattern = Pattern.compile(p);
matcher = pattern.matcher(methodString);
if(matcher.matches()){
advices = getAdvices(p,beanFactory,annotationClass);
methodCache.put(method,advices);
break;
}
}
}
return methodCache;
}

}

AspectJAdvice

保存配置需要切面执行的方法及方法的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package top.jinjinz.spring.aop.aspectj;

import java.lang.reflect.Method;

/**
* 执行属性
* @author jinjin
* @date 2019-04-22
*/
public class AspectJAdvice {
private Method aspectMethod;
private Object aspectTarget;

public AspectJAdvice(Method aspectMethod, Object aspectTarget) {
this.aspectMethod = aspectMethod;
this.aspectTarget = aspectTarget;
}

public Method getAspectMethod() {
return aspectMethod;
}

public void setAspectMethod(Method aspectMethod) {
this.aspectMethod = aspectMethod;
}

public Object getAspectTarget() {
return aspectTarget;
}

public void setAspectTarget(Object aspectTarget) {
this.aspectTarget = aspectTarget;
}
}

AbstractAspectJAdvice

Advice的抽象类,定义基本功能,执行配置的切面方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package top.jinjinz.spring.aop.aspectj;

import top.jinjinz.spring.aop.Advice;
import top.jinjinz.spring.aop.annotation.AopProxyUtils;
import top.jinjinz.spring.aop.intercept.Joinpoint;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
* 基类 {@link top.jinjinz.spring.aop.Advice}
* @author jinjin
* @date 2019-04-22
*/
public abstract class AbstractAspectJAdvice implements Advice {

private AspectJAdvice aspectJAdvice;

public AbstractAspectJAdvice(AspectJAdvice aspectJAdvice) {
this.aspectJAdvice = aspectJAdvice;
}

protected Object invokeAdviceMethod(Joinpoint joinPoint, Object returnValue,
Throwable tx) throws Throwable{
Class<?> [] paramTypes =
this.aspectJAdvice.getAspectMethod().getParameterTypes();
if(paramTypes.length == 0){
return this.aspectJAdvice.getAspectMethod().invoke(
aspectJAdvice.getAspectTarget());
}else{
Object [] args = new Object[paramTypes.length];
for (int i = 0; i < paramTypes.length; i ++) {
if(paramTypes[i] == Throwable.class){
args[i] = tx;
}else if(paramTypes[i] == Object.class){
args[i] = returnValue;
}else if(paramTypes[i] == Joinpoint.class){
args[i] = joinPoint;
}
}
return this.aspectJAdvice.getAspectMethod().invoke(
AopProxyUtils.getTargetObject(aspectJAdvice.getAspectTarget()),args);
}
}
}

MethodBeforeAdviceInterceptor

方法调用之前执行,继承了AbstractAspectJAdvice类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package top.jinjinz.spring.aop.adapter;

import top.jinjinz.spring.aop.aspectj.AbstractAspectJAdvice;
import top.jinjinz.spring.aop.aspectj.AspectJAdvice;
import top.jinjinz.spring.aop.intercept.Joinpoint;
import top.jinjinz.spring.aop.intercept.MethodInterceptor;
import top.jinjinz.spring.aop.intercept.MethodInvocation;

import java.lang.reflect.Method;

/**
* 拦截器-before
* @author jinjin
* @date 2019-04-19
*/
public class MethodBeforeAdviceInterceptor extends AbstractAspectJAdvice
implements MethodInterceptor {
private Joinpoint joinPoint;
public MethodBeforeAdviceInterceptor(AspectJAdvice aspectJAdvice) {
super(aspectJAdvice);
}

private void before(Method method,Object[] args,Object target) throws Throwable{
super.invokeAdviceMethod(this.joinPoint,null,null);
}
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
this.joinPoint = methodInvocation;
before(methodInvocation.getMethod(), methodInvocation.getArguments(),
methodInvocation.getThis());
return methodInvocation.proceed();
}
}

AfterReturningAdviceInterceptor

方法调用之后执行,继承了AbstractAspectJAdvice类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package top.jinjinz.spring.aop.adapter;

import top.jinjinz.spring.aop.aspectj.AbstractAspectJAdvice;
import top.jinjinz.spring.aop.aspectj.AspectJAdvice;
import top.jinjinz.spring.aop.intercept.Joinpoint;
import top.jinjinz.spring.aop.intercept.MethodInterceptor;
import top.jinjinz.spring.aop.intercept.MethodInvocation;

import java.lang.reflect.Method;

/**
* 拦截器-after
* @author jinjin
* @date 2019-04-22
*/
public class AfterReturningAdviceInterceptor extends AbstractAspectJAdvice implements MethodInterceptor {
private Joinpoint joinPoint;
public AfterReturningAdviceInterceptor(AspectJAdvice aspectJAdvice) {
super(aspectJAdvice);
}

private void afterReturning(Object retVal,Method method, Object[] args,
Object target) throws Throwable{
super.invokeAdviceMethod(this.joinPoint,null,null);
}
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Object retVal = methodInvocation.proceed();
this.joinPoint = methodInvocation;
this.afterReturning(retVal,methodInvocation.getMethod(),
methodInvocation.getArguments(),methodInvocation.getThis());
return retVal;
}
}

AopProxyUtils

获取aop代理前的原始类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package top.jinjinz.spring.aop.annotation;

import top.jinjinz.spring.aop.AdvisedSupport;
import top.jinjinz.spring.aop.AopProxy;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

/**
* aop工具类
* @author jinjin
* @date 2019-04-22
*/
public class AopProxyUtils {
public static Object getTargetObject(Object proxy) throws Exception{
if(!isAopProxy(proxy)){ return proxy; }
return getProxyTargetObject(proxy);
}

private static boolean isAopProxy(Object object){
return Proxy.isProxyClass(object.getClass());
}


private static Object getProxyTargetObject(Object proxy) throws Exception{
Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
h.setAccessible(true);
AopProxy aopProxy = (AopProxy) h.get(proxy);
Field advised = aopProxy.getClass().getDeclaredField("advised");
advised.setAccessible(true);
AdvisedSupport advisedSupport = (AdvisedSupport)advised.get(aopProxy);
return getTargetObject(advisedSupport.getTarget());
}


}

spring-core

实现Spring的IOC容器及依赖注入功能

注解定义

注解模块,实现@Autowrited@Service@RequestParam@RequestMapping@Controller等注解

  • @Autowired

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package top.jinjinz.spring.beans.factory.annotation;
    import java.lang.annotation.*;
    /**
    * 自动装配注解
    * @author jinjin
    * @date 2019-03-25
    */
    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Autowired {
    String value() default "";
    }
  • @Service

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package top.jinjinz.spring.beans.factory.annotation;
    import java.lang.annotation.*;
    /**
    * Service注解
    * @author jinjin
    * @date 2019-03-25
    */
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Service {
    String value() default "";
    }
  • @Component

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package top.jinjinz.spring.beans.factory.annotation;
    import java.lang.annotation.*;
    /**
    * 组件标识
    * @author jinjin
    * @date 2019-04-18
    */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Component {
    String value() default "";
    }
  • @RequestParam

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package top.jinjinz.spring.beans.factory.annotation;
    import java.lang.annotation.*;
    /**
    * 请求参数注解
    * @author jinjin
    * @date 2019-03-25
    */
    @Target({ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RequestParam {
    String value() default "";
    }
  • @RequestMapping

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package top.jinjinz.spring.beans.factory.annotation;
    import java.lang.annotation.*;
    /**
    * 请求地址映射注解
    * @author jinjin
    * @date 2019-03-25
    */
    @Target({ElementType.TYPE,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RequestMapping {
    String value() default "";
    }
  • @Controller

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package top.jinjinz.spring.beans.factory.annotation;
    import java.lang.annotation.*;
    /**
    * 控制器注解
    * @author jinjin
    * @date 2019-03-25
    */
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Controller {
    String value() default "";
    }

接口定义

BeanFactory

创建Bean的工厂,也就是IOC容器,BeanFactory 作为基础的接口类,定义了 IOC 容器的基本功能。

1
2
3
4
5
6
7
8
9
10
11
12
package top.jinjinz.spring.beans.factory; 

/**
* 定义IOC容器的基本功能接口
* author:jinjin
* Date:2019/4/13 22:19
*/
public interface BeanFactory {

//根据bean的名字,获取在IOC容器中得到bean实例
Object getBean(String name) throws Exception;
}

ApplicationContext

定义ApplicationContext接口,继承BeanFactory的功能并扩展其功能,默认初始化所有bean。

1
2
3
4
5
6
7
8
9
10
11
12
package top.jinjinz.spring.context;

import top.jinjinz.spring.beans.factory.BeanFactory;

/**
* 扩展BeanFactory功能
* author:jinjin
* Date:2019/4/14 3:44
*/
public interface ApplicationContext extends BeanFactory {
String[] getBeanDefinitionNames();
}

BeanDefinition

存储对Bean的解析信息类,BeanDefinition存储了解析后的Bean元信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package top.jinjinz.spring.beans.factory.config;

/**
* 存储对Bean的解析信息
* author:jinjin
* Date:2019/4/13 23:16
*/
public interface BeanDefinition {

void setBeanClassName(String beanClassName);

String getBeanClassName();

void setLazyInit(boolean lazyInit);

boolean isLazyInit();

void setFactoryBeanName(String factoryBeanName);

String getFactoryBeanName();
}

BeanPostProcessor

在初始化bean时回调接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package top.jinjinz.spring.beans.factory.config;

import top.jinjinz.spring.beans.factory.BeanFactory;

/**
* 允许自定义修改代理的实例的工厂钩子
* @author jinjin
* @date 2019-04-18
*/
public interface BeanPostProcessor {
//为在Bean的初始化前提供回调入口
default Object postProcessBeforeInitialization(Object bean, String beanName,
BeanFactory beanFactory) throws Exception {
return bean;
}

//为在Bean的初始化之后提供回调入口
default Object postProcessAfterInitialization(Object bean, String beanName,
BeanFactory beanFactory) throws Exception {
return bean;
}
}

BeanDefinitionReader

将配置信息解析为BeanDefinition的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package top.jinjinz.spring.beans.factory.support;

import java.io.IOException;

/**
* 将Bean定义信息读取为BeanDefinition
* @author jinjin
* @date 2019-04-15
*/
public interface BeanDefinitionReader {

BeanDefinitionRegistry getRegistry();

int loadBeanDefinitions(String location) throws IOException;

int loadBeanDefinitions(String... locations) throws IOException;
}

BeanDefinitionRegistry

注册BeanDefinition并保存的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package top.jinjinz.spring.beans.factory.support;

import top.jinjinz.spring.beans.factory.config.BeanDefinition;
import top.jinjinz.spring.beans.factory.config.BeanPostProcessor;

/**
* 保存BeanDefinition的容器
* @author jinjin
* @date 2019-04-15
*/
public interface BeanDefinitionRegistry {

void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws Exception;

void removeBeanDefinition(String beanName);

BeanDefinition getBeanDefinition(String beanName);

boolean containsBeanDefinition(String beanName);

String[] getBeanDefinitionNames();

int getBeanDefinitionCount();

//增加bean回调处理器
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
}

功能实现

DefaultListableBeanFactory

BeanFactory的默认实现类,也实现了BeanDefinitionRegistry接口,保存了BeanDefinition信息,实现了基本的依赖注入功能和IOC容器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package top.jinjinz.spring.beans.factory.support;

import top.jinjinz.spring.beans.factory.BeanFactory;
import top.jinjinz.spring.beans.factory.annotation.Autowired;
import top.jinjinz.spring.beans.factory.config.BeanDefinition;
import top.jinjinz.spring.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* BeanFactory的默认实现
* author:jinjin
* Date:2019/4/14 4:00
*/
public class DefaultListableBeanFactory implements BeanFactory,BeanDefinitionRegistry {
//存储注册信息的BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap =
new ConcurrentHashMap<>(256);

/** 缓存singleton类型实例: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** 正在创建的bean集合 */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));

/** 创建bean时应用的处理器 */
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();

@Override
public Object getBean(String name) throws Exception{
return doGetBean(name);
}

@Override
public void registerBeanDefinition(String beanName,
BeanDefinition beanDefinition) throws Exception{
this.beanDefinitionMap.put(beanName, beanDefinition);
}

@Override
public void removeBeanDefinition(String beanName) {
this.beanDefinitionMap.remove(beanName);
}

@Override
public BeanDefinition getBeanDefinition(String beanName){
BeanDefinition beanDefinition = this.beanDefinitionMap.get(beanName);
return beanDefinition;
}

@Override
public boolean containsBeanDefinition(String beanName) {
return this.beanDefinitionMap.containsKey(beanName);
}

@Override
public String[] getBeanDefinitionNames() {
return this.beanDefinitionMap.keySet().toArray(new String[0]);
}

@Override
public int getBeanDefinitionCount() {
return this.beanDefinitionMap.size();
}

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
}


//从容器中获取beanDefinition,如果没有创建实例则创建实例并初始化
private Object doGetBean(final String beanName) throws Exception{
//先从缓存中取已经被创建的singleton类型的Bean
Object singletonInstance = this.singletonObjects.get(beanName);
if(null != singletonInstance){
return singletonInstance;
}

//循环引用
if(singletonsCurrentlyInCreation.contains(beanName)){
throw new RuntimeException(beanName+"发生循环引用");
}

//开始创建单例的实例
Object instance = null;
BeanDefinition beanDefinition = this.beanDefinitionMap.get(beanName);
if(null == beanDefinition){
throw new RuntimeException(beanName+"不存在");
}

Class<?> clazz = Class.forName(beanDefinition.getBeanClassName());
instance = clazz.newInstance();
populateBean(instance,beanDefinition,clazz);
instance = applyBeanPostProcessorsBeforeInitialization(instance, beanName);

//将类名和注解值都作为key值放入map,接口将类型名称存入
this.singletonObjects.put(beanDefinition.getBeanClassName(),instance);
this.singletonObjects.put(beanDefinition.getFactoryBeanName(),instance);
return instance;
}

//调用BeanPostProcessor 初始化调用实例之前的处理方法
private Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws Exception {
Object result = existingBean;
//遍历容器为所创建的Bean添加的所有BeanPostProcessor
for (BeanPostProcessor beanProcessor : beanPostProcessors) {
//Bean实例对象在初始化之前做一些自定义的处理操作
Object current = beanProcessor.postProcessBeforeInitialization(result,
beanName,this);
if (current == null) {
return result;
}
result = current;
}
return result;
}

//调用BeanPostProcessor 初始化调用实例之后的处理方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean,
String beanName) throws Exception {

Object result = existingBean;
//遍历容器为所创建的Bean添加的所有BeanPostProcessor
for (BeanPostProcessor beanProcessor : beanPostProcessors) {
//Bean实例对象在初始化之后做一些自定义的处理操作
Object current = beanProcessor.postProcessAfterInitialization(result,
beanName,this);
if (current == null) {
return result;
}
result = current;
}
return result;
}

//对字段进行依赖注入,只注入对象类型,基本类型未判断
private void populateBean(Object instance, BeanDefinition beanDefinition,
Class<?> clazz) throws Exception{
Object autowiredBean;
//加入正在创建的bean集合中,防止循环引用
singletonsCurrentlyInCreation.add(beanDefinition.getBeanClassName());
//获得所有的字段
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
//只对加了注解的字段进行依赖注入
if(!field.isAnnotationPresent(Autowired.class)){ continue;}

Autowired autowired = field.getAnnotation(Autowired.class);

String autowiredBeanName = autowired.value().trim();
if("".equals(autowiredBeanName)){
autowiredBeanName = field.getType().getName();
}

//访问私有变量
field.setAccessible(true);

try {
//获取需要注入的实例
autowiredBean = this.singletonObjects.get(autowiredBeanName);
//如果需要注入的实例还未创建,则创建
if(null == autowiredBean){
//递归创建bean
getBean(autowiredBeanName);
}
field.set(instance,autowiredBean);
} catch (IllegalAccessException e) {
e.printStackTrace();
}

}
//注入完成后删除
singletonsCurrentlyInCreation.remove(beanDefinition.getBeanClassName());
}
}

AbstractApplicationContext

定义ApplicationContext的抽象类,其中有启动容器方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package top.jinjinz.spring.context.support;


import top.jinjinz.spring.beans.factory.BeanFactory;
import top.jinjinz.spring.context.ApplicationContext;


/**
* ApplicationContexts顶层抽象类
* author:jinjin
* Date:2019/4/14 3:35
*/
public abstract class AbstractApplicationContext implements ApplicationContext {

public void refresh() throws Exception{
BeanFactory beanFactory = obtainFreshBeanFactory();
}

protected BeanFactory obtainFreshBeanFactory() throws Exception{
//具体实现调用子类容器的refreshBeanFactory()方法
refreshBeanFactory();
BeanFactory beanFactory = getBeanFactory();
return beanFactory;
}

protected abstract void refreshBeanFactory() throws Exception;

public abstract BeanFactory getBeanFactory();
}

PropertiesApplicationContext

定义Properties配置文件的启动方式,扫描注解类并注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package top.jinjinz.spring.context.support;

import top.jinjinz.spring.beans.factory.BeanFactory;
import top.jinjinz.spring.beans.factory.config.BeanDefinition;
import top.jinjinz.spring.beans.factory.config.BeanPostProcessor;
import top.jinjinz.spring.beans.factory.support.BeanDefinitionRegistry;
import top.jinjinz.spring.beans.factory.support.DefaultListableBeanFactory;
import top.jinjinz.spring.context.annotation.AnnotatedBeanDefinitionReader;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

/**
* PropertiesApplication方式
* @author jinjin
* @date 2019-04-15
*/
public class PropertiesApplicationContext extends AbstractApplicationContext
implements BeanDefinitionRegistry {

private Properties config = new Properties();

private final String SCAN_PACKAGE = "scanPackage";

private Set<Class<?>> annotatedClasses = new LinkedHashSet<>();

private DefaultListableBeanFactory beanFactory;


public PropertiesApplicationContext(String... locations) throws Exception{
InputStream is =
this.getClass().getClassLoader().getResourceAsStream(
locations[0].replace("classpath:",""));
try {
config.load(is);
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null != is){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
doScanner(config.getProperty(SCAN_PACKAGE));
refresh();
}

@Override
protected void refreshBeanFactory() throws Exception{
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
this.beanFactory = beanFactory;
loadBeanDefinitions(beanFactory);
}

@Override
public BeanFactory getBeanFactory() {
return beanFactory;
}

@Override
public Object getBean(String beanName) throws Exception {
return this.beanFactory.getBean(beanName);
}

@Override
public void registerBeanDefinition(String beanName,
BeanDefinition beanDefinition) throws Exception{
this.beanFactory.registerBeanDefinition(beanName,beanDefinition);
}

@Override
public void removeBeanDefinition(String beanName) {
this.beanFactory.removeBeanDefinition(beanName);
}

@Override
public BeanDefinition getBeanDefinition(String beanName) {
return this.beanFactory.getBeanDefinition(beanName);
}

@Override
public boolean containsBeanDefinition(String beanName) {
return this.beanFactory.containsBeanDefinition(beanName);
}

@Override
public String[] getBeanDefinitionNames() {
return this.beanFactory.getBeanDefinitionNames();
}

@Override
public int getBeanDefinitionCount() {
return this.beanFactory.getBeanDefinitionCount();
}

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
this.beanFactory.addBeanPostProcessor(beanPostProcessor);
}

private void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws Exception{
AnnotatedBeanDefinitionReader reader =
new AnnotatedBeanDefinitionReader(beanFactory);
if (!this.annotatedClasses.isEmpty()) {
reader.register(this.annotatedClasses.toArray(new Class<?>[0]));
}

//将注册的bean进行初始化
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName:beanNames) {
getBean(beanName);
}
}

private void doScanner(String scanPackage) throws Exception {
URL url = this.getClass().getClassLoader().getResource(
"/" + scanPackage.replaceAll("\\.", "/"));
if (null == url) {
return;
}
File dir = new File(url.getFile());
File[] dirs = dir.listFiles();
if (null == dirs) {
return;
}
//找出所有的文件名称,去除.class后缀
for (File file : dirs) {
//如果是文件夹则递归
if (file.isDirectory()) {
doScanner(scanPackage + "." + file.getName());
} else {
Class<?> beanClass = Class.forName(
scanPackage + "." + file.getName().replace(".class", "").trim());
if (!beanClass.isInterface()) {
this.annotatedClasses.add(beanClass);
}
}
}
}
}

AbstractBeanDefinition

BeanDefinition的基本实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package top.jinjinz.spring.beans.factory.support;

import top.jinjinz.spring.beans.factory.config.BeanDefinition;

/**
* BeanDefinition基本实现
* author:jinjin
* Date:2019/4/13 23:27
*/
public abstract class AbstractBeanDefinition implements BeanDefinition{

private volatile String beanClass;

private boolean lazyInit = false;

private String factoryBeanName;

protected AbstractBeanDefinition(){};

protected AbstractBeanDefinition(BeanDefinition original) {
setBeanClassName(original.getBeanClassName());
setLazyInit(original.isLazyInit());
setFactoryBeanName(original.getFactoryBeanName());
}

@Override
public void setBeanClassName(String beanClassName) {
this.beanClass = beanClassName;
}

@Override
public String getBeanClassName() {
return beanClass;
}

@Override
public void setLazyInit(boolean lazyInit) {
this.lazyInit = lazyInit;
}

@Override
public boolean isLazyInit() {
return this.lazyInit;
}

@Override
public void setFactoryBeanName(String factoryBeanName) {
this.factoryBeanName = factoryBeanName;
}

@Override
public String getFactoryBeanName() {
return this.factoryBeanName;
}
}

AbstractBeanDefinitionReader

BeanDefinitionReader基本实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package top.jinjinz.spring.beans.factory.support;

import java.io.IOException;

/**
* BeanDefinitionReader基本实现
* @author jinjin
* @date 2019-04-15
*/
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader{
private final BeanDefinitionRegistry registry;

protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
this.registry = registry;
}

@Override
public final BeanDefinitionRegistry getRegistry() {
return this.registry;
}

@Override
public int loadBeanDefinitions(String... locations) throws IOException {
int counter = 0;
for (String location : locations) {
counter += loadBeanDefinitions(location);
}
return counter;
}

}

AnnotatedBeanDefinitionReader

扫描注解类,注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package top.jinjinz.spring.context.annotation;

import top.jinjinz.spring.aop.annotation.After;
import top.jinjinz.spring.aop.annotation.AfterThrowing;
import top.jinjinz.spring.aop.annotation.Aspect;
import top.jinjinz.spring.aop.annotation.Before;
import top.jinjinz.spring.aop.aspectj.AspectJAdvice;
import top.jinjinz.spring.aop.autoproxy.AutoProxyCreator;
import top.jinjinz.spring.beans.factory.annotation.AnnotatedBeanDefinition;
import top.jinjinz.spring.beans.factory.annotation.Component;
import top.jinjinz.spring.beans.factory.annotation.Controller;
import top.jinjinz.spring.beans.factory.annotation.Service;
import top.jinjinz.spring.beans.factory.config.BeanDefinition;
import top.jinjinz.spring.beans.factory.config.BeanPostProcessor;
import top.jinjinz.spring.beans.factory.support.BeanDefinitionRegistry;

import java.lang.reflect.Method;
import java.util.*;

/**
* 注解bean类的注册器
* @author jinjin
* @date 2019-04-15
*/
public class AnnotatedBeanDefinitionReader {

private final BeanDefinitionRegistry registry;

private Map<String,List<AspectJAdvice>> aspectMethods = new HashMap<>();

private List<String> patterns = new ArrayList<>();

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this.registry = registry;
}

public void register(Class<?>... annotatedClasses) throws Exception{
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
BeanPostProcessor autoProxyCreator =
new AutoProxyCreator(aspectMethods,patterns);
registry.addBeanPostProcessor(autoProxyCreator);
}

public void registerBean(Class<?> annotatedClass) throws Exception{
//IOC容器中只注册加了指定注解的类
if(isRegister(annotatedClass)){
doRegisterBean(annotatedClass);
parseBean(annotatedClass);
}
}

//解析bean的其他注解信息并注册其功能
private void parseBean(Class<?> annotatedClass) {
//注册aop注解类
if(annotatedClass.isAnnotationPresent(Aspect.class)){
parseAspect(annotatedClass);
}
}

//注册Aspect信息
private void parseAspect(Class<?> annotatedClass) {
List<AspectJAdvice> aspectJAdviceList;
Method[] methods=annotatedClass.getMethods();
String pointCut = "";
for (Method method:methods) {
if(method.isAnnotationPresent(Before.class)){
pointCut = method.getAnnotation(Before.class).value();
}
if(method.isAnnotationPresent(After.class)){
pointCut = method.getAnnotation(After.class).value();
}
if(method.isAnnotationPresent(AfterThrowing.class)){
pointCut = method.getAnnotation(AfterThrowing.class).pointcut();
}
if("".equals(pointCut)){
continue;
}
if(!patterns.contains(pointCut)){
patterns.add(pointCut);
}
aspectJAdviceList=aspectMethods.get(pointCut);
if(null == aspectJAdviceList){
aspectJAdviceList = new ArrayList<>();
}
aspectJAdviceList.add(new AspectJAdvice(method,annotatedClass.getName()));
aspectMethods.put(pointCut,aspectJAdviceList);
}
}

private boolean isRegister(Class<?> annotatedClass){
return annotatedClass.isAnnotationPresent(Component.class)||
annotatedClass.isAnnotationPresent(Controller.class)||
annotatedClass.isAnnotationPresent(Service.class);
}

//注册bean信息
private <T> void doRegisterBean(Class<T> annotatedClass) throws Exception{
registry.registerBeanDefinition(annotatedClass.getName(),doCreateBeanDefinition(
toLowerFirstCase(
annotatedClass.getSimpleName()),annotatedClass.getName()));
Class<?> [] interfaces = annotatedClass.getInterfaces();
for (Class<?> i : interfaces) {
registry.registerBeanDefinition(
i.getName(),doCreateBeanDefinition(i.getName(),annotatedClass.getName()));
}
}

private BeanDefinition doCreateBeanDefinition(String factoryBeanName,
String beanClassName){
BeanDefinition beanDefinition = new AnnotatedBeanDefinition();

beanDefinition.setBeanClassName(beanClassName);
beanDefinition.setFactoryBeanName(factoryBeanName);
return beanDefinition;
}

private String toLowerFirstCase(String simpleName) {
char [] chars = simpleName.toCharArray();
chars[0] += 32;
return String.valueOf(chars);
}
}

spring-webmvc

基于servlet实现webmvc

接口定义

HandlerAdapter

执行方法并动态匹配参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package top.jinjinz.spring.web.servlet;

import top.jinjinz.spring.web.servlet.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* 执行Handler的方法,动态匹配参数
* @author jinjin
* @date 2019-04-17
*/
public interface HandlerAdapter {
ModelAndView handle(HttpServletRequest request, HttpServletResponse response,
HandlerMethod handler) throws Exception;
}

HandlerMapping

Handler映射处理器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package top.jinjinz.spring.web.servlet;

import top.jinjinz.spring.web.servlet.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;

/**
* Handler映射处理器
* @author jinjin
* @date 2019-04-17
*/
public interface HandlerMapping {

HandlerMethod getHandler(HttpServletRequest request) throws Exception;
}

功能实现

DispatcherServlet

Servlet的启动类,作为启动入口实现核心逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package top.jinjinz.spring.web.servlet;


import top.jinjinz.spring.context.ApplicationContext;
import top.jinjinz.spring.context.support.PropertiesApplicationContext;
import top.jinjinz.spring.web.servlet.method.HandlerMethod;
import top.jinjinz.spring.web.servlet.method.HandlerMethodAdapter;
import top.jinjinz.spring.web.servlet.method.HandlerMethodMapping;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
* 启动入口
* @author jinjin
* @date 2019-04-13
*/
public class DispatcherServlet extends HttpServlet {

private HandlerMapping handlerMapping;

private HandlerAdapter handlerAdapter;

public DispatcherServlet(){ super(); }

/**
* 初始化,加载配置文件
*/
public void init(ServletConfig config) throws ServletException {
try {
PropertiesApplicationContext context =
new PropertiesApplicationContext("application.properties");
initStrategies(context);
}catch (Exception e){
e.printStackTrace();
}

//提示信息
System.out.println("mvc is init");
}


protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}


/**
* 执行业务处理
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try{
//匹配对应方法
doDispatch(req,resp);
}catch(Exception e){
resp.getWriter().write("500 Exception,Details:\r\n"
+ Arrays.toString(e.getStackTrace()).replaceAll("\\[|\\]", "")
.replaceAll(",\\s", "\r\n"));
}
}

private void doDispatch(HttpServletRequest req,HttpServletResponse resp)
throws Exception{
HandlerMethod handler = handlerMapping.getHandler(req);
if(null == handler){
resp.getWriter().write("404 Not Found");
return;
}
ModelAndView mv = handlerAdapter.handle(req,resp,handler);
//resp.getWriter().write(mv.getModel().values().toString());
}

//初始化策略
private void initStrategies(ApplicationContext context) {
//多文件上传的组件
initMultipartResolver(context);
//初始化本地语言环境
initLocaleResolver(context);
//初始化模板处理器
initThemeResolver(context);
//初始化Handler映射处理器
initHandlerMappings(context);
//初始化参数适配器
initHandlerAdapters(context);
//初始化异常拦截器
initHandlerExceptionResolvers(context);
//初始化视图预处理器
initRequestToViewNameTranslator(context);
//初始化视图转换器
initViewResolvers(context);
//FlashMap管理器
initFlashMapManager(context);
}

private void initFlashMapManager(ApplicationContext context) {
}

private void initViewResolvers(ApplicationContext context) {
}

private void initRequestToViewNameTranslator(ApplicationContext context) {
}

private void initHandlerExceptionResolvers(ApplicationContext context) {
}

private void initHandlerAdapters(ApplicationContext context) {
this.handlerAdapter = new HandlerMethodAdapter();
}

private void initHandlerMappings(ApplicationContext context) {
this.handlerMapping = new HandlerMethodMapping(context);
}

private void initThemeResolver(ApplicationContext context) {
}

private void initLocaleResolver(ApplicationContext context) {
}

private void initMultipartResolver(ApplicationContext context) {
}
}

HandlerMethod

封装Handler的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package top.jinjinz.spring.web.servlet.method;

import java.lang.reflect.Method;

/**
* 封装Handler的信息
* @author jinjin
* @date 2019-04-17
*/
public class HandlerMethod {

private final Object bean;

private final Method method;

public HandlerMethod(Object bean, Method method) {
this.bean = bean;
this.method = method;
}

public Object getBean() {
return bean;
}

public Method getMethod() {
return method;
}
}

HandlerMethodAdapter

HandlerAdapter实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package top.jinjinz.spring.web.servlet.method;

import top.jinjinz.spring.beans.factory.annotation.RequestParam;
import top.jinjinz.spring.web.servlet.HandlerAdapter;
import top.jinjinz.spring.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
* HandlerAdapter实现类
* @author jinjin
* @date 2019-04-17
*/
public class HandlerMethodAdapter implements HandlerAdapter {

@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response,
HandlerMethod handler) throws Exception {

//把方法的形参列表和request的参数列表所在顺序进行对应
Map<String,Integer> paramIndexMapping = new HashMap<>();

//提取方法中加了注解的参数
Annotation[] [] pa = handler.getMethod().getParameterAnnotations();
for (int i = 0; i < pa.length ; i ++) {
for(Annotation a : pa[i]){
if(a instanceof RequestParam){
String paramName = ((RequestParam) a).value();
if("".equals(paramName.trim())){
//todo 参数没有加注解则反射获取参数名称
}else {
paramIndexMapping.put(paramName, i);
}
}
}
}

//提取方法中的request和response参数
Class<?> [] paramsTypes = handler.getMethod().getParameterTypes();
for (int i = 0; i < paramsTypes.length ; i ++) {
Class<?> type = paramsTypes[i];
if(type == HttpServletRequest.class ||
type == HttpServletResponse.class){
paramIndexMapping.put(type.getName(),i);
}
}

//获得方法的形参列表
Map<String,String[]> params = request.getParameterMap();

//实参列表
Object [] paramValues = new Object[paramsTypes.length];

for (Map.Entry<String, String[]> parm : params.entrySet()) {
String value = Arrays.toString(parm.getValue())
.replaceAll("\\[|\\]","").replaceAll("\\s",",");

if(!paramIndexMapping.containsKey(parm.getKey())){continue;}

int index = paramIndexMapping.get(parm.getKey());
paramValues[index] = caseStringValue(value,paramsTypes[index]);
}

if(paramIndexMapping.containsKey(HttpServletRequest.class.getName())) {
int reqIndex = paramIndexMapping.get(HttpServletRequest.class.getName());
paramValues[reqIndex] = request;
}

if(paramIndexMapping.containsKey(HttpServletResponse.class.getName())) {
int respIndex = paramIndexMapping.get(HttpServletResponse.class.getName());
paramValues[respIndex] = response;
}

Object result = handler.getMethod().invoke(handler.getBean(),paramValues);
if(result == null || result instanceof Void){ return null; }

boolean isModelAndView = handler.getMethod().getReturnType() ==
ModelAndView.class;
if(isModelAndView){
return (ModelAndView) result;
}
return null;
}

private Object caseStringValue(String value, Class<?> paramsType) {
if(String.class == paramsType){
return value;
}
//如果是int
if(Integer.class == paramsType){
return Integer.valueOf(value);
}
else if(Double.class == paramsType){
return Double.valueOf(value);
}

return value;
}
}

HandlerMethodMapping

HandlerMapping的实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package top.jinjinz.spring.web.servlet.method;

import top.jinjinz.spring.aop.annotation.AopProxyUtils;
import top.jinjinz.spring.beans.factory.annotation.Controller;
import top.jinjinz.spring.beans.factory.annotation.RequestMapping;
import top.jinjinz.spring.context.ApplicationContext;
import top.jinjinz.spring.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;

/**
* HandlerMapping的实现类
* @author jinjin
* @date 2019-04-17
*/
public class HandlerMethodMapping implements HandlerMapping {

private final MappingRegistry mappingRegistry = new MappingRegistry();

public HandlerMethodMapping(ApplicationContext context) {
initHandlerMethod(context);
}


@Override
public final HandlerMethod getHandler(HttpServletRequest request) throws Exception {
String url = request.getRequestURI();
String contextPath = request.getContextPath();
url = url.replace(contextPath, "").replaceAll("/+", "/");
return this.mappingRegistry.getHandlerMethod(url);
}


private void initHandlerMethod(ApplicationContext context) {
String [] beanNames = context.getBeanDefinitionNames();
try {
for (String beanName : beanNames) {

Object bean = context.getBean(beanName);
Object target = AopProxyUtils.getTargetObject(bean);

Class<?> clazz = target.getClass();

//只对加了@Controller注解的类进行初始化
if(!clazz.isAnnotationPresent(Controller.class)){
continue;
}

String baseUrl = "";
//获取Controller的url配置
if(clazz.isAnnotationPresent(RequestMapping.class)){
RequestMapping requestMapping =
clazz.getAnnotation(RequestMapping.class);
baseUrl = requestMapping.value();
}

//获取Method的url配置
Method[] methods = clazz.getMethods();
for (Method method : methods) {

//没有加RequestMapping注解的直接忽略
if(!method.isAnnotationPresent(RequestMapping.class)){ continue; }

//映射URL
RequestMapping requestMapping =
method.getAnnotation(RequestMapping.class);

// /demo/query 字符串处理
// (//demo//query)
String regex = ("/" + baseUrl + "/" + requestMapping.value().
replaceAll("\\*",".*")).replaceAll("/+", "/");

this.mappingRegistry.register(regex,target,method);
System.out.println("Mapped " + regex + "," + method);
}
}
}catch (Exception e){
e.printStackTrace();
}
}

private HandlerMethod createHandlerMethod(Object handler, Method method) {
return new HandlerMethod(handler, method);
}

class MappingRegistry {

private final Map<String, MappingRegistration<String>> registry =
new HashMap<>();

private final Map<String, HandlerMethod> mappingLookup = new LinkedHashMap<>();

public Map<String, HandlerMethod> getMappings() {
return this.mappingLookup;
}

public HandlerMethod getHandlerMethod(String mappings) {
return this.mappingLookup.get(mappings);
}

public void register(String mapping, Object handler, Method method) {
HandlerMethod handlerMethod = createHandlerMethod(handler, method);
this.mappingLookup.put(mapping, handlerMethod);
}
}

private static class MappingRegistration<T> {

private final T mapping;

private final HandlerMethod handlerMethod;

public MappingRegistration(T mapping, HandlerMethod handlerMethod) {
this.mapping = mapping;
this.handlerMethod = handlerMethod;
}

public T getMapping() {
return this.mapping;
}

public HandlerMethod getHandlerMethod() {
return this.handlerMethod;
}
}

}

功能测试

spring-test

service

配置Service

1
2
3
4
5
6
7
8
9
10
package top.jinjinz.spring.test.service; 

/**
* Demo Service
* @author jinjin
* @date 2019-03-25
*/
public interface DemoService {
String hello(String name);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package top.jinjinz.spring.test.service.impl;

import top.jinjinz.spring.beans.factory.annotation.Service;
import top.jinjinz.spring.test.service.DemoService;

/**
* Demo Service实现
* @author jinjin
* @date 2019-03-25
*/
@Service
public class DemoServiceImpl implements DemoService {

@Override
public String hello(String name) {
String hello = "hello "+name;
System.out.println("执行方法返回:"+hello);
return hello;
}
}

controller

配置Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package top.jinjinz.spring.test.controller;

import top.jinjinz.spring.beans.factory.annotation.Autowired;
import top.jinjinz.spring.beans.factory.annotation.Controller;
import top.jinjinz.spring.beans.factory.annotation.RequestMapping;
import top.jinjinz.spring.beans.factory.annotation.RequestParam;
import top.jinjinz.spring.test.service.DemoService;

import javax.servlet.http.HttpServletResponse;

/**
* Demo控制器
* @author jinjin
* @date 2019-03-25
*/
@Controller
@RequestMapping("/demo")
public class DemoController {

@Autowired
private DemoService demoService;

@RequestMapping("/hello")
public void hello(@RequestParam("name") String name, HttpServletResponse resp) throws Exception{
resp.getWriter().write(demoService.hello(name));
}
}

aspect

配置切面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package top.jinjinz.spring.test.aspect;

import top.jinjinz.spring.aop.annotation.After;
import top.jinjinz.spring.aop.annotation.Aspect;
import top.jinjinz.spring.aop.annotation.Before;
import top.jinjinz.spring.aop.intercept.Joinpoint;
import top.jinjinz.spring.beans.factory.annotation.Component;

import java.util.Arrays;

/**
* 日志切面
* @author jinjin
* @date 2019-04-18
*/
@Aspect
@Component
public class LogAspect {

//使用正则
@Before("public .* top.jinjinz.spring.test.service..*Service..*(.*)")
//在调用一个方法之前,执行before方法
public void before(Joinpoint joinPoint){
System.out.println("执行方法前");
}

@After("public .* top.jinjinz.spring.test.service..*Service..*(.*)")
//在调用一个方法之后,执行after方法
public void after(Joinpoint joinPoint){
System.out.println("执行方法后");
}

}

application.properties

application.properties作为配置文件,配置所需要的属性

1
scanPackage=top.jinjinz.spring

web.xml

配置自定义Servlet DispatcherServlet及设置匹配请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Web Application</display-name>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>top.jinjinz.spring.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

测试效果