ApplicationContext
职责作用
该类是模拟Spring的IOC环境,为bean的生命周期提供存活环境。所以它维护了类池、BeanDefinition池、单例池和切面池。
private static Class config; private static ListaopClassList=new CopyOnWriteArrayList ();; //切面池 private static List aopPointCutList= new CopyOnWriteArrayList (); //切点池 private static List classList=new CopyOnWriteArrayList (); //类池 private static Map beanDefinitionMap = new ConcurrentHashMap ();//BeanDefinition池 private static Map singletonObjects = new ConcurrentHashMap ();//单例池
而为了实现类的装载和bean的实例化及其维护,ApplicationContext的职责流程是这样的。
(1)加载配置类:这是所有Spring的ApplicationContext都会做的,当然不同的ApplicationContext子类有的是加载xml文件,有的是加载配置类。而我这边是模拟了AnnotationConfigApplicationContext,即加载配置类的方式初始化IOC容器。
(2)扫描注解:在配置类上获取@ComponentScan注解,获取所需要扫描注解的文件路径。这里为了获取所有class文件,用了递归算法扫描。
(3)装载Class文件:对于存在@Component的类进行加载,该类是属于框架维护的
(4)生成BeanDefinition:在所有的类都被加载完之后,对类池中每个类生成对应的BeanDefinition,该对象定义了实例对象Scope范围、是否有代理、是否有别名、切面、是否懒加载等等。
(5)初始化非懒加载的bean:上述步骤都做完了,就对非懒加载且单例的类进行实例化,实例化中遇到类的属性有@Autowired注解,则进行判断(是否有单例对象,是否为框架维护的等),再注入。实例化完成后,则判断是否实现
AopBeanPostProcessor接口,有则进行代理对象的生成。最后在放进单例池进行维护。AopBeanPostProcessor接口就是模拟了Spring的BeanPostProcessor接口,也就是后置处理器,模拟了bean初始化前后进行的操作。
配置类
配置类上实现了@ComponentScan、@Configuration注解,ApplicationContext在初始化时候,会判断该类合法性并加载该类。
@com.CmJava.annotation.Configuration
@ComponentScan("com.CmJava")
public class SpringConfiguration implements Configuration{
}
基本方法
treeFile方法,递归遍历包扫描路径,将扫描到的切面类和bean类维护起来。
private void treeFile(File[] files, String path, ClassLoader classLoader) {
if (files.length == 0) {
return;
}
String filePath = "";
String classPath = "";
Class<?> aClass = null;
for (File file : files) {
if (file.isDirectory()) {
if (file.listFiles().length > 0) {
treeFile(file.listFiles(), path, classLoader);
}
} else {
try {
filePath = file.toString().replace("\\", "/");
classPath = filePath.substring(filePath.indexOf(path), filePath.indexOf(".class")).replace("/", ".");
aClass = classLoader.loadClass(classPath);
//获取切面
if (aClass.isAnnotationPresent(Aspect.class)) {
String pointCut = "";
boolean flag = true;
List<String> notPointCut = new ArrayList<>();
for (Method method : aClass.getDeclaredMethods()) {
if (method.isAnnotationPresent(Pointcut.class)) {
pointCut = method.getName();
} else {
String value = methodGetAopAnnotationValue(method);
value = value.substring(0, value.indexOf("("));
notPointCut.add(value);
}
}
//判断通知和切点的对应关系是否有误
for (String notPointCutName : notPointCut) {
if (!notPointCutName.equals(pointCut)) {
flag = false;
break;
}
}
if (flag) {
aopClassList.add(aClass);
}
}
//获取框架管理的的class
if (aClass.isAnnotationPresent(Component.class)) {
classList.add(aClass);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
creatBeanDefinition方法,将上个方法获取到的类进行读取扫描,创建BeanDefinition对象
private void creatBeanDefinition(List<Class> classList, List<Class> aopClassList, Map<String, BeanDefinition> beanDefinitionMap) {
String beanName = "";
Class beanClass = null;
String scope = "";
BeanDefinition beanDefinition = null;
boolean isLazy = false;
//生成BeanDefinition
for (Class aClass : classList) {
if (aClass.isAnnotationPresent(Lazy.class)) {
isLazy = true;
} else {
isLazy = false;
}
if (aClass.isAnnotationPresent(Scope.class)) {
scope = ((Scope) aClass.getAnnotation(Scope.class)).value();
} else {
scope = "singleton";
}
if (((Component) aClass.getAnnotation(Component.class)).value().equals("")) {
beanName = aClass.getName();
} else {
beanName = ((Component) aClass.getAnnotation(Component.class)).value();
}
beanDefinition = new BeanDefinition(beanName, aClass.getName(), aClass, scope, isLazy);
beanDefinitionMap.put(aClass.getName(), beanDefinition);
}
//获取切入点,注入到BeanDefinition
String access = "";
String pointCut = "";
String classString = "";
String pointCutMethod = "";
String[] classSplit = null;
Class beanClassAop = null;
for (Class aClass : aopClassList) {
for (Method method : aClass.getDeclaredMethods()) {
if (method.isAnnotationPresent(Pointcut.class)) {
pointCut = method.getAnnotation(Pointcut.class).value();
if (pointCutMatch(pointCut)) {
pointCut = pointCut.substring(10, pointCut.indexOf("))") + 1);
access = pointCut.split(" ")[0];
classString = pointCut.split(" ")[1];
classSplit = classString.substring(0, classString.lastIndexOf("(..)")).split("\\.");
//切点方法
pointCutMethod = classSplit[classSplit.length - 1];
//切点类全限定名
classString = classString.substring(0, classString.indexOf("." + pointCutMethod));
if (beanDefinitionMap.containsKey(classString)) {
beanClassAop = beanDefinitionMap.get(classString).getBeanClass();
if (pointCutMethod.equals("*")) {
for (Method method1 : beanClassAop.getDeclaredMethods()) {
beanDefinitionMap.get(classString).getPointCut().put(method1, aClass);
break;
}
} else {
for (Method method1 : beanClassAop.getDeclaredMethods()) {
if (method1.getName().equals(pointCutMethod)) {
beanDefinitionMap.get(classString).getPointCut().put(method1, aClass);
break;
}
}
}
}
}
break;
}
}
}
}
instanceNotLazySingletonBean方法,实例化非懒加载的单例bean
private void instanceNotLazySingletonBean(Map<String, BeanDefinition> beanDefinitionMap) {
BeanDefinition beanDefinition = null;
Object bean = null;
String beanName = "";
for (String beanClassName : beanDefinitionMap.keySet()) {
beanDefinition = beanDefinitionMap.get(beanClassName);
if (beanDefinition.getScope().equals("singleton")) {
if (!singletonExistByClassName(beanClassName)) {
bean = doCreateBean(beanClassName);
if (!beanDefinition.getBeanName().equals(beanClassName)) {
//有bean别名
singletonObjects.put(beanDefinition.getBeanName(), bean);
} else {
//无bean别名
singletonObjects.put(beanClassName, bean);
}
}
}
}
}
doCreateBean方法,创建实例化对象
private Object doCreateBean(String beanClassName) {
Object bean = null;
if (beanDefinitionMap.containsKey(beanClassName)) {
//存在bean定义就创建
Class beanClass = beanDefinitionMap.get(beanClassName).getBeanClass();
try {
//实例化
bean = beanClass.newInstance();
//属性填充
Object fieldObject = null;
String fieldClassName = "";
for (Field field : beanClass.getDeclaredFields()) {
if (field.isAnnotationPresent(Autowired.class)) {
fieldClassName = field.getType().getName();
//Autowired注入
if (beanDefinitionMap.get(fieldClassName).getPointCut().size()>0){
throw new RuntimeException("Autowired未考虑代理对象的注入");
}
//是否给框架管理
if (beanDefinitionMap.containsKey(fieldClassName) || childBeanDefinitionExist(fieldClassName) != null) {
if (singletonExistByClassName(fieldClassName)) {
//原生对象
fieldObject = getSingletonByClassName(fieldClassName);
} else {
//无对象
fieldObject = doCreateBean(fieldClassName);
singletonObjects.put(field.getName(), fieldObject);
}
}else {
fieldObject = doCreateBean(fieldClassName);
}
} else {
fieldObject = field.getType().newInstance();
}
field.setAccessible(true);
try {
field.set(bean, fieldObject);
}catch (Exception e){
System.out.println("代理对象不支持Autowire注入");
field.set(bean, field.getType().newInstance());
}
}
//AOP
if (bean instanceof AopBeanPostProcessor) {
//BeanPostProcessor,初始化之前
bean = ((AopBeanPostProcessor) bean).postProcessBeforeInitialization(bean, beanClassName);
//一些其他的初始化逻辑,就不写了
//...
//BeanPostProcessor,初始化之后,AOP
bean = ((AopBeanPostProcessor) bean).postProcessAfterInitialization(bean, beanClassName, beanDefinitionMap.get(beanClassName).getPointCut());
}
} catch (InstantiationException e) {
e.printStackTrace();
System.out.println("请确认是否存在有参构造覆盖无参构造的情况");
} catch (IllegalAccessException e) {
e.printStackTrace();
System.out.println("请确认无参构造是否私有");
}
} else if (childBeanDefinitionExist(beanClassName) != null) {
//存在bean子类定义则创建
BeanDefinition beanDefinition = childBeanDefinitionExist(beanClassName);
String className = beanDefinition.getBeanClassName();
if (singletonExistByClassName(className)) {
bean = getSingletonByClassName(className);
} else {
bean = doCreateBean(className);
}
} else {
//框架不管理该bean
Class<?> aClass = null;
try {
aClass = this.getClass().getClassLoader().loadClass(beanClassName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
bean = doCreateBeanNotBySpring(aClass);
}
if (bean != null) {
return bean;
} else {
throw new RuntimeException("实例化bean失败");
}
}
/**
* Autowired非框架管理的bean
*
* @param aClass
* @return
*/
private Object doCreateBeanNotBySpring(Class<?> aClass) {
//未完成
Object bean = null;
try {
bean = aClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return bean;
}
getBean方法,获取创建好的单例或者返回原型对象
public Object getBean(String beanClassName) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanClassName);
String beanName = beanDefinition.getBeanName();
Object bean = null;
if (beanDefinition.getPointCut().size() > 0) {
//是个代理对象
if (beanDefinition.getScope().equals("singleton")) {
//获取单例对象
if (singletonExistByProxyClassName(beanClassName)) {
//非懒加载
bean = singletonObjects.get(beanName);
} else {
//懒加载
bean = doCreateBean(beanName);
singletonObjects.put(beanName, bean);
}
} else if (beanDefinition.getScope().equals("prototype")) {
//获取原型对象
bean = doCreateBean(beanName);
}
} else {
//不是代理对象
if (beanDefinition.getScope().equals("singleton")) {
//获取单例对象
if (singletonExistByClassName(beanClassName)) {
//非懒加载
bean = singletonObjects.get(beanName);
} else {
//懒加载
bean = doCreateBean(beanName);
singletonObjects.put(beanName, bean);
}
} else if (beanDefinition.getScope().equals("prototype")) {
//获取原型对象
bean = doCreateBean(beanName);
}
}
return bean;
}
注解
IOC注解
该框架创建了如下几个IOC注解:
(1)@Autowired:依赖注入,将框架维护的实例对象注入。
(2)@Component:标注为框架维护的bean
(3)@Lazy:懒加载,仅在使用者调用时才创建该类实例
(4)@Scope:bean类型,单例或原型
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.CONSTRUCTOR})//注解在变量,方法上
public @interface Autowired {
//beanName
String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.TYPE)//注解在类上
public @interface Component {
//beanName
String value() default "";
}
//懒加载
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.TYPE)//注解在类上
public @interface Lazy {
}
//设置生成bean的模式
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.TYPE)//注解在类上
public @interface Scope {
//默认单例模式
String value() default "singleton";
}
配置类注解
该框架创建了如下几个配置类注解:
(1)@Configuration:标注配置类。
(2)@ComponentScan:表明框架需要扫描注解的路径
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.TYPE)//注解在类上
public @interface Configuration {
}
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.TYPE)//注解在类上
public @interface ComponentScan {
//包路径
String value() default "";
}
AOP注解
该框架创建了如下几个AOP注解:
(1)@Aspect:标注切面类。
(2)@Pointcut:标注切面类的切点
(3)@Before:前置通知
(4)@After:后置通知
(5)@AfterReturning:最终通知
(6)@AfterThrowing:异常通知
(7)@Around:环绕通知
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.TYPE)//注解在类上
public @interface Aspect {
}
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.CONSTRUCTOR})//注解在变量,方法上
public @interface Pointcut {
//切入点
String value();
}
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.METHOD)//注解在方法上
public @interface Before {
//切入点
String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.METHOD)//注解在方法上
public @interface After {
//切入点
String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.METHOD)//注解在方法上
public @interface AfterReturning {
//切入点
String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.METHOD)//注解在方法上
public @interface AfterThrowing {
//切入点
String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.METHOD)//注解在方法上
public @interface Around {
//切入点
String value() default "";
}
AOP和IOC实现
AOP和IOC实现流程图
如图所示
评论区