Spring从零基础到深层次剖析
所有的代码地址:https://gitee.com/zyxscuec/spring.git
(前提还是得具备JavaSE和Java Web基础的技术,这里的零基础是针对spring掌握的零基础)
Spring-HelloWorld
一、体验一下IOC(Inversion of Control)控制反转
首先构造一个POJO(全称为:Plain Ordinary Java Object)类,简单理解为不包含业务逻辑的单纯用来存储数据的 java类。
package com.zhou.spring.test_001; /** * @author zhouyanxiang * @create 2020-07-2020/7/11-18:18 */ public class Person { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
然后通过maven的方式来下载我们需要的jar包
以下是pom.xml的内容
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>spring-01</artifactId> <version>1.0-SNAPSHOT</version> <properties> <org.springframework.version>5.1.10.RELEASE</org.springframework.version> <commons-logging.version>1.2</commons-logging.version> <junit.version>4.12</junit.version> </properties> <dependencies> <!-- Spring核心依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${org.springframework.version}</version> </dependency> <!-- Spring beans包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${org.springframework.version}</version> </dependency> <!-- Spring 容器包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework.version}</version> </dependency> <!-- Spring容器依赖包,将第三方库整合进Spring应用上下文,提供支持 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${org.springframework.version}</version> </dependency> <!-- Spring aop依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${org.springframework.version}</version> </dependency> <!-- Spring aspects依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${org.springframework.version}</version> </dependency> <!-- aspectj依赖 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.4</version> </dependency> <!-- commons-logging依赖 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>${commons-logging.version}</version> </dependency> <!-- Spring jdbc依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${org.springframework.version}</version> </dependency> <!--Spring事物依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${org.springframework.version}</version> </dependency> <!-- Spring web依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${org.springframework.version}</version> </dependency> <!--Spring webmvc依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework.version}</version> </dependency> <!-- Spring test依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${org.springframework.version}</version> </dependency> <!-- junit 单元测试依耐 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> </project>
紧接着,我们创建一个配置的xml文件,命名为applicationContext1.xml(其他的命名方式也可以),那么我们就可以创造一个类通过spring方式来获取Person类的信息。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="person" class="com.zhou.spring.test_001.Person"> </bean> </beans>
创建一个普通类,我命名他为SpringStart,具体代码如下
package com.zhou.spring.test_001; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author zhouyanxiang * @create 2020-07-2020/7/11-18:20 */ public class SpringStart { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext1.xml"); Person person = (Person) ctx.getBean("person"); person.setAge(26); person.setName("zhangsan"); System.out.println(person.getAge()); System.out.println(person.getName()); } }
这样我们运行这个类,最后会打印出 26 zhangsan。
其中,ClassPathXmlApplicationContext(“applicationContext1.xml”)引号里面的就是刚才创建的xml的文件名,然后ctx.getBean(“person”);引号里面的就是applicationContext1.xml配置的bean的id。
如果我们不用spring的IOC(Inversion of Control)控制反转管理对象的话,那我们平常就应该会这么写
package com.zhou.spring.test_001; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author zhouyanxiang * @create 2020-07-2020/7/11-18:20 */ public class SpringStart { public static void main(String[] args) { Person person = new Person(); person.setAge(26); person.setName("zhangsan"); System.out.println(person.getAge()); System.out.println(person.getName()); } }
打印结果如下
二、体验DI(Dependency Injection)依赖注入
在上述过程中,已经体验过了IOC,那么接下来体验DI
我们新增加了一个普通的POJO类Food
package com.zhou.spring.test_002; /** * @author zhouyanxiang * @create 2020-07-2020/7/12-8:49 */ public class Food { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
同时在配置类applicationContext.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" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="person" class="com.zhou.spring.test_002.Person"> <constructor-arg name="name" value="Tom"></constructor-arg> <constructor-arg name="age" value="28"></constructor-arg> <constructor-arg name="food" ref="food"></constructor-arg> </bean> <bean id="food" class="com.zhou.spring.test_002.Food"></bean> </beans>
是添加构造器,可以使用依赖注入,不用调用自身的set和get方法了,
最后我们重新在SpringStater类里面来输出
package com.zhou.spring.test_002; import org.apache.commons.lang3.builder.ToStringBuilder; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author zhouyanxiang * @create 2020-07-2020/7/11-18:20 */ public class SpringStart { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = (Person) ctx.getBean("person"); System.out.println(ToStringBuilder.reflectionToString(person)); } }
打印之后结果如下
三、体验集合类在applicationContext.xml里面的配置
在上述的步骤下,继续在Person里面添加集合类的属性
package com.zhou.spring.test_002; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; /** * @author zhouyanxiang * @create 2020-07-2020/7/11-18:18 */ public class Person { private String name; private Integer age; private Food food; private Properties properties; private List<String> list; private Set<String> set; private Map<String, String> map; public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } public Set<String> getSet() { return set; } public void setSet(Set<String> set) { this.set = set; } public Map<String, String> getMap() { return map; } public void setMap(Map<String, String> map) { this.map = map; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Food getFood() { return food; } public void setFood(Food food) { this.food = food; } // public Person(String name, Integer age, Food food) { // super(); // this.name = name; // this.age = age; // this.food = food; // } }
然后配置文件也做相应的修改,一下就是applicationContext.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" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="person" class="com.zhou.spring.test_002.Person"> <property name="name" value="Tom"></property> <property name="age" value="25"></property> <property name="food" ref="food"></property> <property name="properties"> <value> project = test name = BruceLi age = 55 </value> </property> <property name="list"> <array> <value>111</value> <value>222</value> <value>333</value> </array> </property> <!--set集合设置了多个以后会像高中学集合一样的,里面重复的值只会算一个--> <property name="set"> <array> <value>111</value> <value>111</value> <value>111</value> </array> </property> <property name="map"> <!-- <map>--> <!-- <entry key="zhangsan" value="no1"></entry>--> <!-- <entry key="lisi" value="no2"></entry>--> <!-- </map>--> <props> <prop key="zhangsan" > 23 </prop> <prop key="lisi"> 24 </prop> </props> </property> </bean> <bean id="food" class="com.zhou.spring.test_002.Food"> <constructor-arg name="name" value="Lucy"></constructor-arg> <constructor-arg name="age" value="30"></constructor-arg> </bean> </beans>
其中
<property name="properties"> <value> project = test name = BruceLi age = 55 </value> </property>
设置是为集合类专用的,然后set和list集合都可以这样用,但是map由于是键值对的特点,需要换一点
<property name="map"> <props> <prop key="zhangsan" > 23 </prop> <prop key="lisi"> 24 </prop> </props> </property>
或者这种
<property name="map"> <map> <entry key="zhangsan" value="no1"></entry> <entry key="lisi" value="no2"></entry> </map>--> </property>
最后打印结果