文章目录
首先就是创建一个普通的Java工程,起名TrayagainSpring
然后在 创建两个包 分别为service、spring。service用来存放bean、配置类等,spring包用来存放我们手撸的spring注解等
在service中创建UserService 类,再创建Test类,在Test类中创建我们的spring容器,此时以配置类的形式去创建容器,在service包中创建AppConfig配置类,在spring包里创建CsApplicationContext类,并提供一个参数与构造方法。
CsApplicationContext类
package com.cs.spring;
public class CsApplicationContext {
private Class configClass;
public CsApplicationContext(Class configClass) {
this.configClass = configClass;
}
}
Test类
package com.cs.service;
import com.cs.spring.CsApplicationContext;
public class Test {
public static void main(String[] args) {
//创建spring容器
CsApplicationContext context = new CsApplicationContext(AppConfig.class);
}
}
配置类APPConfig启动要去扫描路径,所以在spring包中定义ComponentScan注解,并提供属性等
package com.cs.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)//表示注解生效的时间
@Target(ElementType.TYPE)//指定注解写的位置
public @interface ComponentScan {
String value() default "";//指定扫描路径
}
package com.cs.service;
import com.cs.spring.ComponentScan;
@ComponentScan("com.cs.service")//指定扫描路径
public class AppConfig {
}
而UserService类一般会在类上加@Component注解表示把这个类定义为一个bean,所以此时再去spring包下写一个Component注解
package com.cs.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)//表示注解生效的时间
@Target(ElementType.TYPE)//指定注解写的位置
public @interface Component {
String value() default "";//给我们当前定义的bean取一个名字。
}
package com.cs.service;
import com.cs.spring.Component;
@Component("userService")//给当前bean指定一个名字
public class UserService {
}
此时我们就有了一个spring容器了,但是没啥用处,spring容器中有个getBean()方法,所以此时再去CsApplicationContext中创建一个getBean方法
package com.cs.spring;
public class CsApplicationContext {
private Class configClass;
public CsApplicationContext(Class configClass) {
this.configClass = configClass;
}
public Object getBean(String beanName){
return null;//暂时这样处理
}
}
此时需要思考下,spring容器里的构造方法和getBean方法需要干什么 ?
我们在外面new一个Spring容器对象,就相当于我们去创建一个spring容器,或者启动一个spring容器,那么在启动spring容器的过程中,spring应该去干什么,他会去干什么?
1.spring扫描底层实现
spring启动首先去扫描,那spring是怎么进行扫描的呢?——通过类上面的@ComponentScan注解指定的路径
通过判断接收到的类,上面有没有ComponentScan注解,
package com.cs.spring;
import java.io.File;
import java.lang.annotation.Annotation;
import java.net.URL;
public class CsApplicationContext {
private Class configClass;
public CsApplicationContext(Class configClass) {
this.configClass = configClass;
//首先去判断你给我的这个类上面有没有ComponentScan这个注解
if (configClass.