简单手写spring

一 前言

手写spring,主要是手写Bean被创建的过程;所以了解bean生命周期中的大致步骤是必要的,bean被创建的大致步骤有:

  1. 实例化
  2. 属性注入
  3. 初始化
  4. 销毁

二 实例化

实例化之前的一些准备工作,创建一个工程,目录结构如下:在这里插入图片描述

// spring测试类
public class TestMySpring {
    public static void main(String[] args) {
        SpringApplicationContext applicationContext = new SpringApplicationContext(ApplicationConfig.class);
    }
}
// spring容器类
public class SpringApplicationContext {
    private Class configClazz;

    public SpringApplicationContext(Class configClazz) {
        this.configClazz = configClazz;
    }
}
// 配置类
@ComponentScan("com.ami.service")
public class ApplicationConfig {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
    String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
    String value() default "";
}
@Component
public class OrderService {
    public void order(){
        System.out.println("生成订单");
    }
}

扫描

在bean被实例化之前需要知道哪些bean需要被创建,因此需要通过配置类中的@ComponentScan注解的路径扫描包,识别带有@Component注解的类,下面的扫描的代码:

public class SpringApplicationContext {
    private Class configClazz;

    public SpringApplicationContext(Class configClazz) throws Exception{
        this.configClazz = configClazz;

        // 扫描配置的包
        scan(configClazz);

    }

    private void scan(Class configClazz) throws Exception{
        // 获取componentScan中的路径
        ComponentScan annotation = (ComponentScan) configClazz.getAnnotation(ComponentScan.class);
        String scanPath = annotation.value();
        String targetPath = scanPath.replace(".", "/");

        // 获取的路径实际上是编译后的相对路径,因此需要借助AppClassLoader获取工作的目录
        ClassLoader classLoader = SpringApplicationContext.class.getClassLoader();
        URL resource = classLoader.getResource(targetPath);
        //D:\code\practice\mypractice\AmiSpring\target\classes\com\ami\service
        File file = new File(resource.getPath());
        if (file.isDirectory()){
            for (File aFile : file.listFiles()) {
                String absolutePath = aFile.getAbsolutePath();
                if (absolutePath.endsWith("class")){
                    // com\ami\service\OrderService
                    String beanPath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
                    // com.ami.service.OrderService
                    String beanLoanPath = beanPath.replace("\\", ".");
                    // 通过类加载器加在目录下的所有class
                    Class<?> beanClass = classLoader.loadClass(beanLoanPath);
                    // 如果含有Component注解,说明这个类是需要进行管理的
                    if (beanClass.isAnnotationPresent(Component.class)){
                        
                    }

                }
            }
        }
    }

}

到这里通过扫描就找到了需要创建的bean。

封装BeanDefinition

​ 找到这些bean之后,spring将它们封装成BeanDefinition并储存到一个map中,以便后续的实例化步骤。增加BeanDefinition类以及修改响应的代码

public class BeanDefinition {
    private Class type;
  	// 保存Scope注解的值,用来描述bean是单例还是多例
    private String scope;

    public Class getType() {
        return type;
    }

    public void setType(Class type) {
        this.type = type;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Scope {
    String value() default "";
}

修改orderService的代码

@Component("orderService")
@Scope("singleton")
public class OrderService {
    public void order(){
        System.out.println("生成订单");
    }
}

修改springApplicationContext的代码,新增一个beanDefinitionMap:

public class SpringApplicationContext {
    private Class configClazz;
    private Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>();

    public SpringApplicationContext(Class configClazz) throws Exception{
        this.configClazz = configClazz;

        // 扫描配置的包
        scan(configClazz);

    }

    private void scan(Class configClazz) throws Exception{
        // 获取componentScan中的路径
        ComponentScan annotation = (ComponentScan) configClazz.getAnnotation(ComponentScan.class);
        String scanPath = annotation.value();
        String targetPath = scanPath.replace(".", "/");

        // 获取的路径实际上是编译后的相对路径,因此需要借助AppClassLoader获取工作的目录
        ClassLoader classLoader = SpringApplicationContext.class.getClassLoader();
        URL resource = classLoader.getResource(targetPath);
        File file = new File(resource.getPath());
        if (file.isDirectory()){
            for (File aFile : file.listFiles()) {
                String absolutePath = aFile.getAbsolutePath();
                if (absolutePath.endsWith("class")){
                    String beanPath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
                    String beanLoanPath = beanPath.replace("\\", ".");
                    Class<?> beanClass = classLoader.loadClass(beanLoanPath);

                    // 如果含有Component注解,说明这个类是需要进行管理的
                    if (beanClass.isAnnotationPresent(Component.class)){
                        Component componentAnnotation = beanClass.getAnnotation(Component.class);
                        String beanName = componentAnnotation.value();

                        BeanDefinition beanDefinition = new BeanDefinition();
                        beanDefinition.setType(beanClass);
                        Scope scopeAnnotation = beanClass.getAnnotation(Scope.class);
                        beanDefinition.setScope(scopeAnnotation.value());

                        beanDefinitionMap.put(beanName,beanDefinition);
                    }

                }
            }
        }
    }

}

实例化bean

经过上面的步骤,已经把所有需要实例化的bean信息存入了BeanDefinitionMap中,现在根据BeanDefinition实例化每一个Bean,如果Bean是单例的需要将它放入单例池(Map<String,Objects>)中:

public class SpringApplicationContext {
    private Class configClazz;
    private Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>();
  	// 单例池
    private Map<String,Object> singleTonObjectMap = new HashMap<>();

    public SpringApplicationContext(Class configClazz) throws Exception{
        this.configClazz = configClazz;

        // 扫描配置的包
        scan(configClazz);

        // 实例化
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
            String beanName = entry.getKey();
            BeanDefinition beanDefinition = entry.getValue();
            Object bean = createBean(beanName, beanDefinition);
            // 单例bean需要存起来
            if ("singleTon".equals(beanDefinition.getScope())){
                singleTonObjectMap.put(beanName,bean);
            }
        }

    }
    
    private Object createBean(String beanName,BeanDefinition beanDefinition)throws Exception{
        Object instance = beanDefinition.getType().getDeclaredConstructor().newInstance();
        return instance;
    }

现在已经完成bean的实例化并且存放到了单例池中,现在来添加一个从单例池中获取Bean的方法:

public class SpringApplicationContext {
    private Class configClazz;
    private Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>();
    private Map<String,Object> singleTonObjectMap = new HashMap<>();

    public SpringApplicationContext(Class configClazz) throws Exception{
        this.configClazz = configClazz;

        // 扫描配置的包
        scan(configClazz);

        // 实例化
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
            String beanName = entry.getKey();
            BeanDefinition beanDefinition = entry.getValue();
            Object bean = createBean(beanName, beanDefinition);
            // 单例bean需要存起来
            if ("singleTon".equals(beanDefinition.getScope())){
                singleTonObjectMap.put(beanName,bean);
            }
        }

    }
	
    public Object getBean(String benaName)throws Exception{
        if (!beanDefinitionMap.keySet().contains(benaName)){
            return null;
        }
        
        Object bean = singleTonObjectMap.get(benaName);
        if (bean != null){
            return bean;
        }
        // 单例池中没有这个bean就创建
        return createBean(benaName,beanDefinitionMap.get(benaName));

    }

修改test类的代码并进行测试:

public class TestMySpring {
    public static void main(String[] args) throws Exception{
        SpringApplicationContext applicationContext = new SpringApplicationContext(ApplicationConfig.class);
        OrderService orderService = (OrderService) applicationContext.getBean("orderService");
        OrderService orderService2 = (OrderService) applicationContext.getBean("orderService");
        System.out.println(orderService);
        System.out.println(orderService2);
        orderService.order();
    }
}

结果输出:

com.ami.service.OrderService@5e2de80c
com.ami.service.OrderService@5e2de80c
生成订单

修改orderService为prototype并测试

@Component("orderService")
@Scope("prototype")
public class OrderService {
    public void order(){
        System.out.println("生成订单");
    }
}

结果输出:

com.ami.service.OrderService@5e2de80c
com.ami.service.OrderService@1d44bcfa
生成订单

三 依赖注入

新增一个UserService类和Autowire的注解,并将UserService作为OrderService的属性:

@Component("userService")
@Scope("singleTon")
public class UserService {

    public void addUser(){
        System.out.println("新增用户");
    }
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {
}
@Component("orderService")
@Scope("singleTon")
public class OrderService {

    @Autowired
    private UserService userService;

    public void order(){
        System.out.println("生成订单");
        System.out.println(userService);
        userService.addUser();
    }
}

依赖注入是bean实例化之后的步骤,bean实例化之后,所有的属性都还没进行赋值,接下来就完成属性赋值,修改createBean:

   private Object createBean(String beanName,BeanDefinition beanDefinition)throws Exception{
        Object instance = beanDefinition.getType().getDeclaredConstructor().newInstance();

        // 属性注入
        Class clazz = beanDefinition.getType();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Autowired.class)) {
                String name = field.getName();
                Object bean = getBean(name);
                field.setAccessible(true);
                field.set(instance,bean);
            }
        }

        return instance;
    }

修改测试类进行测试:

public class TestMySpring {
    public static void main(String[] args) throws Exception{
        SpringApplicationContext applicationContext = new SpringApplicationContext(ApplicationConfig.class);
        OrderService orderService = (OrderService) applicationContext.getBean("orderService");
        orderService.order();
    }
}

结果输出:

生成订单
com.ami.service.UserService@5e481248
新增用户

userService成功注入到orderService中

四 Aware回调

在spring中还有很多aware结尾的接口,比如BeanNameAware接口,这些Aware接口的方法就是在依赖注入之后的步骤中被调用。aware回调代码:

先增加一个BeanNameAware接口:

public interface BeanNameAware {
    void setBeanName(String beanName);
}

让UserService实现BeanNameAware接口

@Component("userService")
@Scope("singleTon")
public class UserService implements BeanNameAware {

    private String beanName;

    public void addUser(){
        System.out.println("新增用户");
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("UserService的bean名字:"+beanName);
        this.beanName = beanName;
    }
}

Aware回调代码:

private Object createBean(String beanName,BeanDefinition beanDefinition)throws Exception{
        Object instance = beanDefinition.getType().getDeclaredConstructor().newInstance();

        // 属性注入
        Class clazz = beanDefinition.getType();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Autowired.class)) {
                String name = field.getName();
                Object bean = getBean(name);
                field.setAccessible(true);
                field.set(instance,bean);
            }
        }

        // aware回调
        if (instance instanceof BeanNameAware) {
            ((BeanNameAware)instance).setBeanName(beanName);
        }

        return instance;
    }

五 初始化

初始化主要是实现一个InitalizingBean接口,初始化和aware接口一样都是在实例化之后的步骤中。新增一个InitalizingBean接口:

public interface InitalizingBean {
    void afterPropertiesSet() ;
}

修改UserService实现InitalizingBean:

@Component("userService")
@Scope("singleTon")
public class UserService implements BeanNameAware, InitalizingBean {

    private String beanName;

    public void addUser(){
        System.out.println("新增用户");
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("UserService的bean名字:"+beanName);
        this.beanName = beanName;
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("UserService的初始化方法正在执行");
    }
}

初始化代码:

private Object createBean(String beanName,BeanDefinition beanDefinition)throws Exception{
        Object instance = beanDefinition.getType().getDeclaredConstructor().newInstance();

        // 属性注入
        Class clazz = beanDefinition.getType();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Autowired.class)) {
                String name = field.getName();
                Object bean = getBean(name);
                field.setAccessible(true);
                field.set(instance,bean);
            }
        }

        // aware回调
        if (instance instanceof BeanNameAware) {
            ((BeanNameAware)instance).setBeanName(beanName);
        }
        
        // 初始化
        if (instance instanceof InitalizingBean){
            ((InitalizingBean)instance).afterPropertiesSet();
        }

        return instance;
    }

六 BeanPostProcessor

BeanPostProcessor接口中有两个方法:初始化前,初始化后;

public interface BeanPostProcessor {
    /**
     * 初始化前方法回调
     * @param bean 实例化的bean
     * @param beanName 
     * @return 可以将入参的Bean返回,也可以新建一个
     */
    Object postProcessBeforeInitialization (Object bean,String beanName);

    /**
     * 初始化后方法回调
     * @param bean 实例化的bean
     * @param beanName
     * @return 可以将入参的Bean返回,也可以返回Bean的代理对象
     */
    Object postProcessAfterInitialization (Object bean,String beanName);
}

修改UserService代码:

@Component("userService")
@Scope("singleTon")
public class UserService implements BeanNameAware, InitalizingBean, BeanPostProcessor {

    private String beanName;

    public void addUser(){
        System.out.println("新增用户");
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("UserService的bean名字:"+beanName);
        this.beanName = beanName;
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("UserService的初始化方法正在执行");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        if (beanName.equals("userService")){
            System.out.println("UserService正在执行初始化前====操作");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (beanName.equals("userService")) {
            System.out.println("UserService正在执行初始化后------操作");
        }
        return bean;
    }
}

增加BeanPostProcessor的两个方法调用的代码,增加一个List<BeanPostProcessor>,在Scan方法内部将实现了BeanPostProcessor接口的类收集,初始化的前后将list进行循环调用:

public class SpringApplicationContext {
    private Class configClazz;
    private Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>();
    private Map<String,Object> singleTonObjectMap = new HashMap<>();
  	// 用来收集BeanPostProcessor
    private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();

    public SpringApplicationContext(Class configClazz) throws Exception{
        this.configClazz = configClazz;

        // 扫描配置的包
        scan(configClazz);

        // 实例化
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
            String beanName = entry.getKey();
            BeanDefinition beanDefinition = entry.getValue();
            Object bean = createBean(beanName, beanDefinition);
            // 单例bean需要存起来
            if ("singleTon".equals(beanDefinition.getScope())){
                singleTonObjectMap.put(beanName,bean);
            }
        }

    }

    public Object getBean(String benaName)throws Exception{
        if (!beanDefinitionMap.keySet().contains(benaName)){
            return null;
        }

        Object bean = singleTonObjectMap.get(benaName);
        if (bean != null){
            return bean;
        }
        // 单例池中没有这个bean就创建
        return createBean(benaName,beanDefinitionMap.get(benaName));

    }

    private Object createBean(String beanName,BeanDefinition beanDefinition)throws Exception{
        Object instance = beanDefinition.getType().getDeclaredConstructor().newInstance();

        // 属性注入
        Class clazz = beanDefinition.getType();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Autowired.class)) {
                String name = field.getName();
                Object bean = getBean(name);
                field.setAccessible(true);
                field.set(instance,bean);
            }
        }

        // aware回调
        if (instance instanceof BeanNameAware) {
            ((BeanNameAware)instance).setBeanName(beanName);
        }

        // 初始化前方法回调
        for (BeanPostProcessor processor : beanPostProcessorList) {
            instance = processor.postProcessBeforeInitialization(instance,beanName);
        }

        // 初始化
        if (instance instanceof InitalizingBean){
            ((InitalizingBean)instance).afterPropertiesSet();
        }

        // 初始化后
        for (BeanPostProcessor processor : beanPostProcessorList) {
            instance = processor.postProcessAfterInitialization(instance,beanName);
        }

        return instance;
    }

    private void scan(Class configClazz) throws Exception{
        // 获取componentScan中的路径
        ComponentScan annotation = (ComponentScan) configClazz.getAnnotation(ComponentScan.class);
        String scanPath = annotation.value();
        String targetPath = scanPath.replace(".", "/");

        // 获取的路径实际上是编译后的相对路径,因此需要借助AppClassLoader获取工作的目录
        ClassLoader classLoader = SpringApplicationContext.class.getClassLoader();
        URL resource = classLoader.getResource(targetPath);
        File file = new File(resource.getPath());
        if (file.isDirectory()){
            for (File aFile : file.listFiles()) {
                String absolutePath = aFile.getAbsolutePath();
                if (absolutePath.endsWith("class")){
                    String beanPath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
                    String beanLoanPath = beanPath.replace("\\", ".");
                    Class<?> beanClass = classLoader.loadClass(beanLoanPath);

                    // 收集postProcessor类型的bean
                    if (BeanPostProcessor.class.isAssignableFrom(beanClass)){
                        BeanPostProcessor postProcessor = (BeanPostProcessor) beanClass.getDeclaredConstructor().newInstance();
                        beanPostProcessorList.add(postProcessor);
                    }

                    // 如果含有Component注解,说明这个类是需要进行管理的
                    if (beanClass.isAnnotationPresent(Component.class)){
                        Component componentAnnotation = beanClass.getAnnotation(Component.class);
                        String beanName = componentAnnotation.value();

                        BeanDefinition beanDefinition = new BeanDefinition();
                        beanDefinition.setType(beanClass);
                        Scope scopeAnnotation = beanClass.getAnnotation(Scope.class);
                        beanDefinition.setScope(scopeAnnotation.value());

                        beanDefinitionMap.put(beanName,beanDefinition);
                    }

                }
            }
        }
    }

}

测试

public class TestSpring {
    public static void main(String[] args) throws Exception {
        SpringApplicationContext context = new SpringApplicationContext(ApplicationConfig.class);
    }
}

结果输出:

// Aware接口
UserService的bean名字:userService 
// 初始化前
UserService正在执行初始化前====操作
// InitalizingBean初始化
UserService的初始化方法正在执行
// 初始化后
UserService正在执行初始化后------操作

七 AOP

Aop代理对象的生成主要是在BeanPostProcessor的postProcessAfterInitialization方法中完成,也就是初始化后的方法,代码:

新增productService接口和实现类:

public interface ProductService {
    void saleProduct();
}

@Component("productService")
@Scope("singleTon")
public class ProductServiceImpl implements ProductService {
    @Override
    public void saleProduct() {
        System.out.println("商品售卖中");
    }
}

新增一个BeanPostProcessor实现类:

@Component("beanPostProcessorImpl")
@Scope("singleTon")
public class BeanPostProcessorImpl implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (beanName.equals("productService")){
            System.out.println("productService正在执行初始后操作");
            Object proxyInstance = Proxy.newProxyInstance(BeanPostProcessorImpl.class.getClassLoader(), 
                    bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("正在执行代理逻辑");
                    return method.invoke(bean,args);
                }
            });
            return proxyInstance;
        }
        return bean;
    }
}

测试类:

public class TestMySpring {
    public static void main(String[] args) throws Exception{
        SpringApplicationContext applicationContext = new SpringApplicationContext(ApplicationConfig.class);
        ProductService productService = (ProductService) applicationContext.getBean("productService");
        productService.saleProduct();
    }
}

结果输出:

productService正在执行初始后操作
正在执行代理逻辑
商品售卖中

八 整体代码

目录:在这里插入图片描述

TestMySpring:

public class TestMySpring {
    public static void main(String[] args) throws Exception{
        SpringApplicationContext applicationContext = new SpringApplicationContext(ApplicationConfig.class);
        ProductService productService = (ProductService) applicationContext.getBean("productService");
        productService.saleProduct();
    }
}

SpringApplicationContext:

public class SpringApplicationContext {
    private Class configClazz;
    private Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>();
    private Map<String,Object> singleTonObjectMap = new HashMap<>();
    private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();

    public SpringApplicationContext(Class configClazz) throws Exception{
        this.configClazz = configClazz;

        // 扫描配置的包
        scan(configClazz);

        // 实例化
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
            String beanName = entry.getKey();
            BeanDefinition beanDefinition = entry.getValue();
            Object bean = createBean(beanName, beanDefinition);
            // 单例bean需要存起来
            if ("singleTon".equals(beanDefinition.getScope())){
                singleTonObjectMap.put(beanName,bean);
            }
        }

    }

    public Object getBean(String benaName)throws Exception{
        if (!beanDefinitionMap.keySet().contains(benaName)){
            return null;
        }

        Object bean = singleTonObjectMap.get(benaName);
        if (bean != null){
            return bean;
        }
        // 单例池中没有这个bean就创建
        return createBean(benaName,beanDefinitionMap.get(benaName));

    }

    private Object createBean(String beanName,BeanDefinition beanDefinition)throws Exception{
        Object instance = beanDefinition.getType().getDeclaredConstructor().newInstance();

        // 属性注入
        Class clazz = beanDefinition.getType();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Autowired.class)) {
                String name = field.getName();
                Object bean = getBean(name);
                field.setAccessible(true);
                field.set(instance,bean);
            }
        }

        // aware回调
        if (instance instanceof BeanNameAware) {
            ((BeanNameAware)instance).setBeanName(beanName);
        }

        // 初始化前方法回调
        for (BeanPostProcessor processor : beanPostProcessorList) {
            instance = processor.postProcessBeforeInitialization(instance,beanName);
        }

        // 初始化
        if (instance instanceof InitalizingBean){
            ((InitalizingBean)instance).afterPropertiesSet();
        }

        // 初始化后
        for (BeanPostProcessor processor : beanPostProcessorList) {
            instance = processor.postProcessAfterInitialization(instance,beanName);
        }

        return instance;
    }

    private void scan(Class configClazz) throws Exception{
        // 获取componentScan中的路径
        ComponentScan annotation = (ComponentScan) configClazz.getAnnotation(ComponentScan.class);
        String scanPath = annotation.value();
        String targetPath = scanPath.replace(".", "/");

        // 获取的路径实际上是编译后的相对路径,因此需要借助AppClassLoader获取工作的目录
        ClassLoader classLoader = SpringApplicationContext.class.getClassLoader();
        URL resource = classLoader.getResource(targetPath);
        File file = new File(resource.getPath());
        if (file.isDirectory()){
            for (File aFile : file.listFiles()) {
                String absolutePath = aFile.getAbsolutePath();
                if (absolutePath.endsWith("class")){
                    String beanPath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
                    String beanLoanPath = beanPath.replace("\\", ".");
                    Class<?> beanClass = classLoader.loadClass(beanLoanPath);

                    // 收集postProcessor类型的bean
                    if (BeanPostProcessor.class.isAssignableFrom(beanClass)){
                        BeanPostProcessor postProcessor = (BeanPostProcessor) beanClass.getDeclaredConstructor().newInstance();
                        beanPostProcessorList.add(postProcessor);
                    }

                    // 如果含有Component注解,说明这个类是需要进行管理的
                    if (beanClass.isAnnotationPresent(Component.class)){
                        Component componentAnnotation = beanClass.getAnnotation(Component.class);
                        String beanName = componentAnnotation.value();

                        BeanDefinition beanDefinition = new BeanDefinition();
                        beanDefinition.setType(beanClass);
                        Scope scopeAnnotation = beanClass.getAnnotation(Scope.class);
                        beanDefinition.setScope(scopeAnnotation.value());

                        beanDefinitionMap.put(beanName,beanDefinition);
                    }

                }
            }
        }
    }

}

初始化相关的接口

public interface InitalizingBean {
    void afterPropertiesSet() ;
}

public interface BeanPostProcessor {
    /**
     * 初始化前方法回调
     * @param bean 实例化的bean
     * @param beanName
     * @return 可以将入参的Bean返回,也可以新建一个
     */
    Object postProcessBeforeInitialization (Object bean,String beanName);

    /**
     * 初始化后方法回调
     * @param bean 实例化的bean
     * @param beanName
     * @return 可以将入参的Bean返回,也可以返回Bean的代理对象
     */
    Object postProcessAfterInitialization (Object bean,String beanName);
}


public interface BeanNameAware {
    void setBeanName(String beanName);
}

BeanDefinition:

public class BeanDefinition {
    private Class type;
    private String scope;

    public Class getType() {
        return type;
    }

    public void setType(Class type) {
        this.type = type;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }
}

ApplicationConfig:

@ComponentScan("com.ami.service")
public class ApplicationConfig {
}

注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
    String value() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
    String value() default "";
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Scope {
    String value() default "";
}

BeanPostProcessorImpl:

@Component("beanPostProcessorImpl")
@Scope("singleTon")
public class BeanPostProcessorImpl implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (beanName.equals("productService")){
            System.out.println("productService正在执行初始后操作");
            Object proxyInstance = Proxy.newProxyInstance(BeanPostProcessorImpl.class.getClassLoader(),
                    bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("正在执行代理逻辑");
                    return method.invoke(bean,args);
                }
            });
            return proxyInstance;
        }
        return bean;
    }
}

OrderService:

@Component("orderService")
@Scope("singleTon")
public class OrderService {

    @Autowired
    private UserService userService;

    public void order(){
        System.out.println("生成订单");
        System.out.println(userService);
        userService.addUser();
    }
}

ProductService:

public interface ProductService {
    void saleProduct();
}

ProductServiceImpl:

@Component("productService")
@Scope("singleTon")
public class ProductServiceImpl implements ProductService {
    @Override
    public void saleProduct() {
        System.out.println("商品售卖中");
    }
}

UserService:

@Component("userService")
@Scope("singleTon")
public class UserService implements BeanNameAware, InitalizingBean, BeanPostProcessor {

    private String beanName;

    public void addUser(){
        System.out.println("新增用户");
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("UserService的bean名字:"+beanName);
        this.beanName = beanName;
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("UserService的初始化方法正在执行");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        if (beanName.equals("userService")){
            System.out.println("UserService正在执行初始化前====操作");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (beanName.equals("userService")) {
            System.out.println("UserService正在执行初始化后------操作");
        }
        return bean;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值