Spring笔记:Hello World
一、Spring简介
关于Spring,多的不用说,但是需要记住并深入理解一句话“Spring是一个轻量级的控制反转(IoC)和面向切面编程(AOP)的框架”。IoC和AOP几乎是面试必问,所以需要在实际开发中深入理解它们的思想及其应用。
1. Spring优点
- Spring是一个开源的免费的框架。
- Spring是一个轻量级的、非入侵式的框架。(添加新功能而不会修改原来的代码)
- 控制反转(IoC),面向切面编程(AOP)。【重点】【核心】
- 支持事务的处理。
2. SSM
SSM(Spring + SpringMVC + MyBatis)是当下最流行的企业级应用开发框架组合,所以Spring其实是Java中非常基础但又是非常重要的一个框架。
3. IoC控制反转(Spring核心思想)
IoC(Inversion of Control)控制反转是Spring的核心思想,通俗快速地理解IOC思想:“不反转”的情况是,当我们创建一个对象之后,我们需要在使用到的地方去更改原来的代码,替换成我们创建的对象,比如在某行代码中我们使用了对象A,当我们想在这个地方换成使用对象B,那么我们在定义好类B之后,需要把对象A修改成对象B;也就是说从某种角度上讲,程序要使用哪个对象,甚至于程序的运行,取决于程序本身,因为程序的代码之前已经写死了,想要改变原来的使用对象或程序的运行行为,就需要更改原来的代码;这就像相当于是把程序运行的控制权交给了编程人员或者程序本身,如果想要“反转”这个控制权,使得我们新加了一个类之后,当我们想要使用这个类时,不用改动原来的代码就可以使用这个类创建的对象,或者说我们想要改变程序的行为时,不用修改原来的代码,只需要添加一个类就可以了,这样的话,程序运行的行为的控制权其实就不在程序本身了,而“反转”到了第三方程序(甚至是用户)上,根据业务需求由第三方程序添加或移除对应的类即可。这个描述不一定百分百准确,重点是理解“控制权”的反转,理解谁控制了什么,谁的控制权又反转到了谁的身上。IoC是一种思想,不仅限于某一种编程语言,当然,想要学习Spring,首先就需要了解IoC控制反转的思想。
其实IoC思想的实现方式有很多中,在Spring中实现IoC控制反转的是IoC容器,其实现方法是DI(Dependency Injection)依赖注入。
4. AOP面向切面编程
AOP面向切面编程,通俗一点讲,就是在不改变现有代码的情况下,自定义一些特殊方法,并让这些方法在指定的某个方法执行之前或之后执行,比如接收到请求之后我想在处理请求之前做一些过滤等操作,在响应返回到浏览器之前做一些格式化处理等。AOP面向切面编程会涉及一些术语,比如切入点、切面等,这些术语刚接触可能不太好理解,多多练习就好理解了。
5. Maven依赖注入
在学习或使用Spring时,可能会用到的一些Maven依赖,我列在这儿,免得到时候我忘了还有再去搜一遍 =_=!
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
</dependencies>
二、Hello World
1. Hello World示例
这个Hello world非常简单,需要重点理解其中应用到的IoC控制反转思想(参见代码注释)。
bean类定义:
public class MyBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "MyBean{" +
"name='" + name + '\'' +
'}';
}
}
beans.xml配置:
在IDEA中直接 new -> XML Configuration File -> Spring Config
就可以生成一个spring的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.xsd">
<!-- 这里配置的每个bean就是一个对象,xml中的对象会由Spring来进行创建,
使用时直接在Spring容器中拿即可。 -->
<bean id="myBean" class="com.yun.pojo.MyBean">
<!-- 可以使用property给创建之后的对象属性进行赋值,
但是前提是这个属性必须要有set方法-->
<property name="name" value="zhangsan"/>
</bean>
</beans>
测试:
import com.yun.pojo.MyBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
// 创建Spring上下文对象(可以理解为一个容器,即Spring容器)
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
// 从容器中获取我们在xml中配置的对象,其实从这里就可以看出,我们自己的程序只是定义了一个类,
// 然后在xml中配置了一个bean,并没有主动去代码中使用new关键字创建对象,所以IoC思想在这里就体现出来了,
// 创建对象的控制权由传统编程思想中的程序本身“反转”到了第三方,即Spring,
// 以后创建对象的控制权就交给Spring了,我们只需要在xml中进行配置bean即可。
MyBean myBean = (MyBean) context.getBean("myBean");
System.out.println(myBean);
}
}
2. Spring对象创建方式
无论使用Spring的那种方式来创建对象,在xml配置加载的时候,里面所有的bean对象都会被一起创建,并不是你去Spring容器里获取的时候才会创建你想要的那个对象。
2.1 默认使用无参构造方法创建对象
Spring默认采用无参构造方法来创建对象,我们知道定义类的时候如果没有定义构造方法,Java会提供一个默认的无参构造方法,但是如果类中定义了有参构造方法,那么Java就不会提供无参构造了,需要自己去定义。所以我们定义bean的时候没有定义构造方法的话,Spring就会使用默认的无参构造方法来创建对象。
bean类定义:
public class MyBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "MyBean{" +
"name='" + name + '\'' +
'}';
}
}
xml配置:
<bean id="myBean" class="com.yun.pojo.MyBean">
<!-- 可以使用property给创建之后的对象属性进行赋值,
但是前提是这个属性必须要有set方法-->
<property name="name" value="zhangsan"/>
</bean>
2.2 根据有参构造方法的参数列表index创建对象
如果类定义了有参构造方法,也可以在xml配置中使用有参构造方法的参数列表index创建对象。
bean类定义:
public class Student {
private int id;
private String name;
private int age;
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
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.xsd">
<bean id="student" class="com.yun.pojo.Student">
<!-- 使用有参构造方法创建对象:constructor-arg标签表示在有参构造方法中给对象属性赋值,
index表示的有参构造方法中参数列表的下标,从0开始 -->
<constructor-arg index="0" value="0"/>
<constructor-arg index="1" value="zhangsan"/>
<constructor-arg index="2" value="18"/>
</bean>
</beans>
2.3 根据有参构造的参数名称创建对象
如果类定义了有参构造方法,也可以在xml配置中使用有参构造方法的参数名称创建对象。
bean类定义:
public class Student {
private int id;
private String name;
private int age;
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
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.xsd">
<bean id="student" class="com.yun.pojo.Student">
<!-- 使用有参构造方法创建对象:constructor-arg标签表示在有参构造方法中给对象属性赋值,
name表示的有参构造方法中对应参数的名称 -->
<constructor-arg name="id" value="0"/>
<constructor-arg name="name" value="zhangsan"/>
<constructor-arg name="age" value="18"/>
</bean>
</beans>