Spring 是什么
Spring 是一个分层的 Java SE/EE 的轻量级框架,能够提高开发人员的开发效率以及系统可维护性
Spring 的特征
非侵入性
Spring 框架的 API 不会在业务逻辑上出现,业务逻辑可以从 Spring 框架快速地移植到其他框架,和环境无关。
容器
作为一个容器,可以管理对象的生命周期、对象与对象的依赖关系,可以通过配置文件来定义对象并设置与其他对象的依赖关系。
IoC
IoC(Inverse of Control,控制反转),既创建被调用者的实例不是由调用者完成,而是由 Spring 容器,并注入调用者。当应用了 IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。即,不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
AOP
通过分离应用的业务逻辑与系统级服务(例如日志和事务管理)进行开发。应用对象只实现它们应该做的——完成业务逻辑。它们并不负责其它的系统级关注点,例如日志或事务支持。
我们可以把日志、安全、事务管理等服务理解成一个「切面」,那么以前这些服务一直是直接写在业务逻辑的代码当中的,这有两点不好:首先业务逻辑不纯净;其次这些服务被很多业务逻辑反复使用,完全可以剥离出来做到复用。那么 AOP 就是这些问题的解决方案, 可以把这些服务剥离出来形成一个「切面」,以期复用,然后将「切面」动态的「织入」到业务逻辑中,让业务逻辑能够享受到此「切面」的服务。
入门代码
引入依赖
<?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>com.mindartisan</groupId>
<artifactId>Spring</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.8.RELEASE</version>
</dependency>
</dependencies>
</project>
创建 HelloSpring 类
package com.mindartisan.spring1;
public class HelloSpring {
private String name;
public void setName(String name) {
this.name = name;
}
public void hello() {
System.out.println("Hello,"+name);
}
}
resources 文件夹下新建配置文件
命名一般为「applicationContext.xml」,代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byName">
<!-- 配置 Bean:其中,class 为 bean 的全类名,通过反射的方式在 IOC 容器中创建 Bean,故要求 Bean 中有无参构造器;id 作用为标识容器中的 bean,id 唯一。-->
<bean id="helloSpring" class="com.mindartisan.spring1.HelloSpring">
<!-- name 会调用类属性的 set 方法-->
<property name="name" value="MindArtisan-Spring"></property>
</bean>
</beans>
创建一个类测试
传统写法
代码:
package com.mindartisan.spring1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
/**
* 传统写法
*/
// 1.实例一个 hellospring 对象
HelloSpring helloSpring=new HelloSpring();
// 2. 设置属性
helloSpring.setName("MindArtisan——traditional");
// 3. 调用方法
helloSpring.hello();
}
}
输出结果:
使用 Spring 后写法
代码:
package com.mindartisan.spring1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
/**
* Spring 写法
*/
// 1. 创建 Spring 的 IOC 容器
// 1.1 ApplicationContext 是一个接口,而 ClassPathXmlApplicationContext 是其实现类,具体可看 UML 图
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2. 从 IOC 容器中获取 Bean 实例
// 2.1 方式一:利用 id 定位到 IOC 容器中的 Bean
HelloSpring helloSpring = ((HelloSpring) applicationContext.getBean("helloSpring"));
// 2.2 方式二:利用类型返回 IOC 容器中的 Bean,要求是 IOC 容器中只有一个该类型的 Bean,否则代码不知道应该返回哪个 Bean,不推荐使用
//HelloSpring helloSpring1 = applicationContext.getBean(HelloSpring.class);
// 3. 调用方法
helloSpring.hello();
}
}
输出:
几点思考
思考一: 这里咱们没有显示地为 name 赋值,咋就成 MindArtisan-Spring 了呢?
答案: 再看下 resources 文件夹下新建配置文件 中的内容即可明白。
思考二: applicationContext 为我们做了什么呢?
分析:
将 Main 类中的下述代码注释:
// 2. 从 IOC 容器中获取 Bean 实例
// 2.1 方式一:利用 id 定位到 IOC 容器中的 Bean
// HelloSpring helloSpring = ((HelloSpring) applicationContext.getBean("helloSpring"));
// 2.2 方式二:利用类型返回 IOC 容器中的 Bean,要求是 IOC 容器中只有一个该类型的 Bean,否则代码不知道应该返回哪个 Bean,不推荐使用
//HelloSpring helloSpring1 = applicationContext.getBean(HelloSpring.class);
// 3. 调用方法
// helloSpring.hello();
并将 HelloSpring 代码改成下述内容:
package com.mindartisan.spring1;
public class HelloSpring {
private String name;
public void setName(String name) {
System.out.println("name 被设置为:"+name);
this.name = name;
}
public void hello() {
System.out.println("Hello,"+name);
}
public HelloSpring() {
System.out.println("Constructor-HelloSpring");
}
}
输出:
答案: 在创建 applicationContext 容器的时会调用构造器,将配置在配置文件中的 Bean 进行初始化,并调用 Bean 的 set 方法对属性赋值。