准备知识
- 自定义注解
- 反射
- Bean 的概念
流程
bean
的依赖注入大致流程 :
- 使用包扫描,扫描指定包下的类,如果带有
@Configuration
则是bean
的配置类 - 扫描
@Configuration
下的方法 所有带@Bean
注解的统统加入一个集合中管理 - 扫描所有指定类下的属性,如果带有
@Autowired
的,则进行注入。
目录结构
Autowired
: 自动装配注解AutowiredScanner
: Autowired 注解扫描器Bean
: bean注解BeanScanner
: bean 注解扫描器Config
: 配置类Configuration
: 配置注解Main
: 测试类PackageScanner
: 包扫描器,代码在这里不给出,详情代码请看 : https://blog.csdn.net/qq_31254489/article/details/114963325Person
: pojo 原生java对象
源码
Configuration.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Configuration{
}
Config.java
@Configuration
public class Config{
@Bean
public Person getPerson(){
return new Person("张三",18);
}
}
Person.java
public class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Bean.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Bean {
}
BeanScanner.java
public class BeanScanner{
public static Object[] init(String packageName) throws URISyntaxException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
List<Object> list = new ArrayList<>();
PackageScanner packageScanner = new PackageScanner();
//包扫描
Class[] classes = packageScanner.scan(packageName);
//遍历类
for (Class clazz : classes) {
//如果类上存在 Configuration 注解
if(clazz.isAnnotationPresent(Configuration.class)){
Method[] methods = clazz.getMethods();
// 实例化config类
Object config = clazz.getConstructor().newInstance();
//遍历方法
for (Method method : methods) {
//如果方法存在 Bean 注解
if(method.isAnnotationPresent(Bean.class)){
//执行方法,并保存bean
list.add(method.invoke(config));
}
}
}
}
return list.toArray();
}
}
Autowired.java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired{
}
AutowiredScanner.java
public class AutowiredScanner {
public static void init(String packageName, Object[] beans) throws URISyntaxException, ClassNotFoundException, IllegalAccessException {
PackageScanner packageScanner = new PackageScanner();
//扫描指定包下的类
Class[] classes = packageScanner.scan(packageName);
//遍历类
for (Class clazz : classes) {
//获取类的属性
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
//如果属性存在 Autowired注解
if (field.isAnnotationPresent(Autowired.class)) {
//判断属性是否可读
if (!field.canAccess(null)) {
field.setAccessible(true);
}
// 遍历已经生成的 bean , 如果和此类相同,则注入
for (Object bean : beans) {
if (bean.getClass().equals(field.getType())) {
//给属性注入 bean 对象
field.set(field, bean);
}
}
}
}
}
}
}
Main.java
public class Main {
@Autowired
public static Person person;
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, URISyntaxException, InvocationTargetException, ClassNotFoundException {
Object[] beans = BeanScanner.init("cn.enncy.spring");
AutowiredScanner.init("cn.enncy.spring", beans);
System.out.println(person);
}
}
Main类执行结果
Person{name='张三', age=18}