Spring的初体验

0.前言 使用spring有什么优势和为什么我们要使用spring

        0.1 Spring 两大特性    IoC(控制反转)/ DI(依赖注⼊) AOP(⾯向切⾯编程)

        在学习软件开发基础的时候,我常常不懂老师为什么要强调使用IOC容器,我直接创建他不香吗?

1.如何使用IOC

        1.1创建maven工程,并添加依赖

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.9</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.20</version>
    </dependency>

        现在pom.xml中注入依赖,分别注入springframework和lombok,lombok便于日后创造get set方法和自动重写toString方法,较为便捷

        1.2创建实体类Student

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student {
    private int age;
    private String name;
    private long id;
    private Address address;
}

        @Data指的是为该类提供读写方法

        @AllArgsConstructor;@NoArgsConstructor则是有参和无参构造

        合理利用Lombok能够减少低效率的代码

        1.3 传统的手动new对象

Student student = new Student();
student.setId(1);
student.setName("张三");
student.setAge(22);
System.out.println(student);

        1.4建立spring.xml 能够实现元素的解耦合,将属性放置在xml文件中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
        <bean id="student" class="Student">
            <property name="id" value="20"></property>
            <property name="age" value="1666"></property>
            <property name="name" value="zhangsan"></property>
            <property name="address" ref="address"></property>
        </bean>
        
</beans>

        1.5从 IoC 中获取对象,通过 id 获取

ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml");
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);

        运行时发现,ClassPathXmlApplicationContext中要填写完整路径名称

2.通过dom4j来重现spring IOC的底层原理

        2.1在maven中注入依赖dom4j

<dependency>
      <groupId>dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>1.1</version>
    </dependency>

        2.2

package com.southwind.ioc;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.lang.reflect.Constructor;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class ClassPathXmlApplicationContext implements ApplicationContext {
 private Map<String,Object> ioc = new HashMap<String, Object>();
 public ClassPathXmlApplicationContext(String path){
 try {
 SAXReader reader = new SAXReader();
 Document document = reader.read("./src/main/resources/"+path);
 Element root = document.getRootElement();
 Iterator<Element> iterator = root.elementIterator();
 while(iterator.hasNext()){
 Element element = iterator.next();
 String id = element.attributeValue("id");
 String className = element.attributeValue("class");
 //通过反射机制创建对象
 Class clazz = Class.forName(className);
 //获取⽆参构造函数,创建⽬标对象
 Constructor constructor = clazz.getConstructor();
 Object object = constructor.newInstance();
 //给⽬标对象赋值
 Iterator<Element> beanIter = element.elementIterator();
 while(beanIter.hasNext()){
 Element property = beanIter.next();
 String name = property.attributeValue("name");
 String valueStr = property.attributeValue("value");
 String ref = property.attributeValue("ref");
 if(ref == null){
 String methodName =
"set"+name.substring(0,1).toUpperCase()+name.substring(1);
 Field field = clazz.getDeclaredField(name);
 Method method =
clazz.getDeclaredMethod(methodName,field.getType());
 //根据成员变量的数据类型将 value 进⾏转换
Object value = null;
 if(field.getType().getName() == "long"){
 value = Long.parseLong(valueStr);
 }
 if(field.getType().getName() == "java.lang.String"){
 value = valueStr;
 }
 if(field.getType().getName() == "int"){
 value = Integer.parseInt(valueStr);
 }
 method.invoke(object,value);通过运⾏时类获取 bean
这种⽅式存在⼀个问题,配置⽂件中⼀个数据类型的对象只能有⼀个实例,否则会抛出异常,因为没有
唯⼀的 bean。
通过有参构造创建 bean
在实体类中创建对应的有参构造函数。
配置⽂件
 }
 ioc.put(id,object);
 }
 }
 } catch (DocumentException e) {
 e.printStackTrace();
 } catch (ClassNotFoundException e){
 e.printStackTrace();
 } catch (NoSuchMethodException e){
 e.printStackTrace();
 } catch (InstantiationException e){
 e.printStackTrace();
 } catch (IllegalAccessException e){
 e.printStackTrace();
 } catch (InvocationTargetException e){
 e.printStackTrace();
 } catch (NoSuchFieldException e){
 e.printStackTrace();
 }
 }
 public Object getBean(String id) {
 return ioc.get(id);
 }
}

上一篇:通用短信平台接口


下一篇:文件类型