发表于: 2018-01-18 22:28:18

1 631


今天完成的事情

讲了小课堂,spring的实现原理

spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高了企业应用的开发效率

spring核心容器:
spring核心容器就是一个超级大工厂,所有的对象都会被当成spring核心容器管理的对象,spring把容器中的一切对象统称为bean。对于spring框架而言,一切Java的对象都是bean
spring使用XML配置文件来管理容器中的bean,配置文件中的bean元素默认以反射方式来调用该类无参数的构造器

spring框架通过反射根据bean元素的class属性指定的类名创建一个Java对象,并以bean元素的id属性的值为key,将该对象放入spring容器中,这个Java对象就成为了spring容器中的bean

property元素是bean元素的子元素,它驱动spring在底层以反射方式执行一次setter方法,name属性值决定执行哪个setter方法,value值或ref值决定执行setter方法的传入参数

定义一个类:

public class A1 implements AA {    

private String name;    

public String getName() {        

    return name;    

}    

public void setName(String name) {        

    this.name = name;    

}    

@Override    

public void say() {        

    System.out.println("---这是--1---");    

}    

@Override    

public String toString() {        

    return "A1{" +                

    "name='" + name + '\'' +                

    '}';    

}

}

spring配置文件:

<bean id="A1" class="principle.spring.A1"/>

运行:

public static void main(String[] args) {        

ApplicationContext cxt = new ClassPathXmlApplicationContext("principle.xml");        

A1 a1 = cxt.getBean("A1",A1.class);        

a1.say();    

}

以上是采用spring来实现的,接下来尝试采用反射来实现类似功能:
建立一个txt文件,用来配置信息:

id=A1

class=principle.spring.A1

name=name

value=Hello,Spring

读取文件信息:

File f1 = new File("C:\\Users\\kelis\\IdeaProjects\\Spring_A\\src\\principle.txt");        

Properties config = new Properties();        

config.load(new FileInputStream(f1));        

String id = config.getProperty("id");        

String className = config.getProperty("class");        

String propertyName = config.getProperty("name");        

propertyName = "set" + propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);        

String value = config.getProperty("value");

利用反射获取对象:

Class clazz = Class.forName(className);        

Constructor constructor = clazz.getConstructor();        

Object obj = constructor.newInstance();

将获取的对象放入容器,这里用HashMap来代替了:

Map testSpring = new HashMap();      

testSpring.put(id,obj);

从容器中根据id获取实例,进行类型转换:

AA aa = (AA) testSpring.get(id);        

aa.say();

还可以模拟spring的设值注入,通过调用setter方法来进行赋值:

Method method = clazz.getMethod(propertyName,String.class);        

method.invoke(obj,value);

最后,可以对这个过程进行封装:

class Context{        

private File f1;        

private Map testSpring;        

public Context(String fileName) throws Throwable{            

    this.f1 = new File(fileName);            

    Properties config = new Properties();            

    config.load(new FileInputStream(f1));            

    String id = config.getProperty("id");            

    String className = config.getProperty("class");            

    String propertyName = config.getProperty("name");            

    propertyName = "set" + propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);            

    String value = config.getProperty("value");            

    Class clazz = Class.forName(className);          

    Constructor constructor = clazz.getConstructor();            

    Object obj = constructor.newInstance();            

    //设置注入            

    System.out.println(propertyName);            

    Method method = clazz.getMethod(propertyName,String.class);            

    method.invoke(obj,value);            

    testSpring = new HashMap();            

    testSpring.put(id,obj);        

}        

Object getBean(String id){            

    return testSpring.get(id);        

}    

}

获取context对象,然后通过getBean方法就可以获取对象了:

Context context = new Context("C:\\Users\\kelis\\IdeaProjects\\Spring_A\\src\\principle.txt");        

AA aa = (AA) context.getBean("A1");        

aa.say();        

System.out.println(aa.toString());

和之前使用spring时的格式基本一致,效果也是一样的
不过这里的txt文件只能配置一个类,不过大体上实现了spring的基本功能


明天的计划

看多线程和IO的知识点


遇到的问题


收获

spring的基本原理



返回列表 返回列表
评论

    分享到