ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

手动实现了一个简单的spring框架

2021-10-16 20:35:18  阅读:106  来源: 互联网

标签:java String 框架 spring 手动 import geng com public


手动实现了一个简单的spring框架

image-20211016191130824

MyBean:

package com.geng.bean;

import com.geng.BeanNameAware;
import com.geng.InitializingBean;
import com.geng.myInterface.Component;

@Component("myBean")
//@Scope("singleton")
public class MyBean implements BeanNameAware, InitializingBean {
    private String nickName;


    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    @Override
    public void setName(String name) {
        System.out.println(name);
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("进行初始化");
    }
}

MyBeanPostProcessor:

package com.geng.bean;

import com.geng.BeanInitializingPostProcessor;
import com.geng.myInterface.Component;

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

@Component("myBeanPostProcessor")
public class MyBeanPostProcessor implements BeanInitializingPostProcessor {
    @Override
    public Object beanBeforeInitializingPostProcessor(String beanName, Object bean) {
        System.out.println("实例化前");
        if("myBean".equals(beanName)){
            bean=new MyBean();
            ((MyBean)bean).setNickName("geng");
            return bean;
        }
        return bean;
    }

    @Override
    public Object beanAfterInitializingPostProcessor(String beanName, Object bean) {
        //其实aop在spring框架中就是使用的PostProcessor接口实现的
        
        //aop中此处应该是进行匹配切点表达式
        if("myService".equals(beanName)){
            //此处只进行了jdk动态代理,其实对于没有接口的类也会进行cglib动态代理
            Object instance= Proxy.newProxyInstance(bean.getClass().getClassLoader(),
                    bean.getClass().getInterfaces(), new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            Object result=method.invoke(bean,args);
                            System.out.println("执行切面逻辑");
                            return result;
                        }
                    });
            return instance;
        }
        return bean;
    }
}

MyService:

package com.geng.bean;

public interface MyService {
    public void test();
    public MyBean getMyBean();
}

MyServiceImpl:

package com.geng.bean;

import com.geng.myInterface.Autowire;
import com.geng.myInterface.Component;
import com.geng.myInterface.Scope;

@Component("myService")
@Scope("prototype")
public class MyServiceImpl implements MyService{
    @Autowire
    private MyBean myBean;

    public void test(){
        System.out.println(myBean);
    }

    public MyBean getMyBean() {
        return myBean;
    }
}

AutowireException:

package com.geng.exception;

public class AutowireException extends Exception{
    public AutowireException(String message) {
        super(message);
    }
}

Autowire:

package com.geng.myInterface;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowire {
    boolean required() default false;
}

Component:

package com.geng.myInterface;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

ComponentScan:

package com.geng.myInterface;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

Scope:

package com.geng.myInterface;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

ApplicationContext:

package com.geng;

import com.geng.exception.AutowireException;
import com.geng.myInterface.Autowire;
import com.geng.myInterface.Component;
import com.geng.myInterface.ComponentScan;
import com.geng.myInterface.Scope;

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class ApplicationContext {
    private Class<Config> configClass;
    private ConcurrentMap<String,BeanDefinition> beanDefinitionMap=new ConcurrentHashMap<>();
    private ConcurrentMap<String,Object> singletonObjects=new ConcurrentHashMap<>();//单例池
    private List<BeanPostProcessor> beanPostProcessors=new CopyOnWriteArrayList<>();
    public ApplicationContext(Class<Config> configClass) {
        this.configClass = configClass;
        scan(configClass);

        //初始化单例池
        for(Map.Entry<String,BeanDefinition> temp:beanDefinitionMap.entrySet()){
            String beanName=temp.getKey();
            BeanDefinition beanDefinition=temp.getValue();
            if("singleton".equalsIgnoreCase(beanDefinition.getScope())){
                singletonObjects.put(beanName,createBean(beanName,beanDefinition));
            }
        }
    }

    private Object createBean(String beanName,BeanDefinition beanDefinition)  {
        Class clazz=beanDefinition.getaClass();
        try {
            Constructor constructor = clazz.getDeclaredConstructor();

            Object o= constructor.newInstance();

            //依赖注入
            for(Field field:clazz.getDeclaredFields()){
                field.setAccessible(true);
                if(field.isAnnotationPresent(Autowire.class)){
                    Autowire autowire=field.getDeclaredAnnotation(Autowire.class);
                    Object temp=getBean(field.getName());
                    if(temp==null&&autowire.required()){
                        throw new AutowireException("注入失败");
                    }
                    field.set(o,temp);
                }
            }

            //Aware接口 回调
            if(o instanceof BeanNameAware){
                ((BeanNameAware) o).setName(beanName);
            }
            for(BeanPostProcessor temp:beanPostProcessors){
                if(temp instanceof BeanInitializingPostProcessor){
                    o=((BeanInitializingPostProcessor)temp).beanBeforeInitializingPostProcessor(beanName,o);
                }
            }
            //InitializingBean接口回调
            if(o instanceof InitializingBean){
                ((InitializingBean) o).afterPropertiesSet();
            }
            for(BeanPostProcessor temp:beanPostProcessors){
                if(temp instanceof BeanInitializingPostProcessor){
                    o=((BeanInitializingPostProcessor)temp).beanAfterInitializingPostProcessor(beanName,o);
                }
            }
            return o;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    //扫描
    private void scan(Class<Config> configClass) {
        this.configClass = configClass;
        ComponentScan componentScan=configClass.getDeclaredAnnotation(ComponentScan.class);
        if(componentScan!=null){
            String path=componentScan.value();
            path=path.replace(".","/");
            ClassLoader classLoader=ApplicationContext.class.getClassLoader();
            URL resource = classLoader.getResource(path);
            File file=new File(resource.getFile());
            if(file.isDirectory()){
                File[] files=file.listFiles();
                for(File temp:files){
                    //System.out.println(temp.getAbsolutePath());
                    String className=temp.getAbsolutePath();
                    className=className.substring(className.indexOf("com"),className.lastIndexOf(".class"));
                    className=className.replace("\\",".");
                    //System.out.println(className);
                    Class<?> clazz=null;
                    try {
                        clazz=classLoader.loadClass(className);
                        if(clazz.isAnnotationPresent(Component.class)){
                            BeanDefinition beanDefinition=new BeanDefinition();
                            beanDefinition.setaClass(clazz);
                            Component component=clazz.getDeclaredAnnotation(Component.class);
                            String beanName=component.value();
                            //判断是否为PostProcessor  实际中肯定不是在这里放进的list,因为在这里放进去有很多问题,但是我们这只是一个演示
                            //所以就不用在意那么多细节了

                            if(BeanPostProcessor.class.isAssignableFrom(clazz)){
                                beanPostProcessors.add((BeanPostProcessor)clazz.newInstance());
                            }
                            //装进beanDefinitionMap
                            if(clazz.isAnnotationPresent(Scope.class)){
                                Scope scope=clazz.getDeclaredAnnotation(Scope.class);
                                beanDefinition.setScope(scope.value());
                            }else{
                                beanDefinition.setScope("singleton");
                            }
                            beanDefinitionMap.put(beanName,beanDefinition);
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }

                }
            }
        }
    }

    public Object getBean(String beanName){
        if(beanDefinitionMap.containsKey(beanName)){
            BeanDefinition beanDefinition=beanDefinitionMap.get(beanName);
            if("singleton".equalsIgnoreCase(beanDefinition.getScope())){
                return singletonObjects.get(beanName);
            }else{
                return createBean(beanName,beanDefinition);
            }
        }else{
            return null;
        }
    }
}

BeanDefinition:

package com.geng;

public class BeanDefinition {
    private Class<?> aClass;
    private String scope;

    public Class<?> getaClass() {
        return aClass;
    }

    public void setaClass(Class<?> aClass) {
        this.aClass = aClass;
    }

    public String getScope() {
        return scope;
    }

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

BeanInitializingPostProcessor:

package com.geng;

public interface BeanInitializingPostProcessor extends BeanPostProcessor {
    Object beanBeforeInitializingPostProcessor(String beanName,Object bean);
    Object beanAfterInitializingPostProcessor(String beanName,Object bean);
}

BeanNameAware:

package com.geng;

public interface BeanNameAware {
    void setName(String name);
}

BeanPostProcessor:

package com.geng;

public interface BeanPostProcessor {

}

Config:

package com.geng;

import com.geng.myInterface.ComponentScan;

@ComponentScan("com.geng.bean")
public class Config {
}

InitializingBean:

package com.geng;

public interface InitializingBean {
    void afterPropertiesSet();
}

myTest:

package com.geng;

import com.geng.bean.MyService;
import com.geng.bean.MyServiceImpl;
import org.junit.Test;

public class myTest {
    @Test
    public void test01(){
        ApplicationContext applicationContext=new ApplicationContext(Config.class);
        MyService myService1 =(MyService)applicationContext.getBean("myService");
        System.out.println(myService1.getMyBean().getNickName());
    }
}

标签:java,String,框架,spring,手动,import,geng,com,public
来源: https://www.cnblogs.com/gengBlog/p/15415164.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有