Spring框架
Spring初解
是一个开源的容器(可以管理所有的组件(或者类))框架
核心是IOC(反转控制)和AOP(面向切面编程)
优点:
- 非侵入式
- 依赖注入
- 面向切面编程
- 容器
- 组件化
- 一站式(spring本身包含表现层的MVC和持久层的JDBC)
IOC(反转控制)
控制指的是资源获取的方式,分为主动式和被动式。
主动式:开发者主动去创建所需的资源(例如:主动去new一个对象)
被动式:资源的获取不是通过开发者主动创建而是由容器来创建(例如:声明对象直接使用而无需去new)
DI(依赖注入)
DI:组件以预先定义好的方式接收来自容器的资源注入,也就是说,容器能知道一个组件(类)运行的时候需要哪些其他组件(类),容器将通过反射的形式将容器中准备好的其他组件(类)的对象注入到这个组件中。
AOP(面向切面编程)
AOP是一种新的方法论,是对传统 OOP(面向对象编程)的补充。AOP操作的主要对象是切面,而切面将横切关注点模块化。
在应用 AOP 编程时,仍然需要定义公共的功能,但可以明确地定义这个功能应用在哪里,以什么方式应用,而不必修改受影响的类。这样一来横切关注点就被模块化到特殊的类里——这样的类我们通常称之为切面。
注:在通过 IOC 容器读取 Bean 的实例之前,需要先将 IOC 容器本身实例化。
Spring 提供了两种 IOC 容器的实现方式 :
- BeanFactory:IOC 容器的基本实现,是 Spring 内部的基础设施,是面向 Spring 本身的,不是提供给开发人员使用的。
- ApplicationContext:BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者 ,几乎所有场合都使用ApplicationContext 而不是底层 的 BeanFactory。
BeanFactory完整继承关系和方法

ApplicationContext 完整继承关系和方法

ClassPathXmlApplicationContext:对应类路径下的 XML 格式的配置文件
FileSystemXmlApplicationContext:对应文件系统中的 XML 格式的配置文件
注:在初始化时就创建单例的 bean,也可以通过配置的方式指定创建的 Bean 是多实例的。
我们可以发现其实在ApplicationContext是没有getBean方法的,调用的是BeanFactory的getBean方法。
IOC测试
我们用GregoriacalnCalendar(日志类)来测试体验一下IOC
TestSpring.java
package controller;
import org.springframework.context.ApplicationContext;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring {
@Test
public void test01(){
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(ac);
Object obj = ac.getBean("cal");
System.out.println(obj);
//销毁ac对象
//((AbstractApplicationContext)ac).close();
}
}
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:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 构造器创建对象 -->
<bean id="cal" class="java.util.GregoriacalnCalendar"></bean>
</beans>
样例输出:
org.springframework.context.support.ClassPathXmlApplicationContext@1cab0bfb: startup date [Sun Aug 23 10:49:10 CST 2019]; root of context hierarchy
java.util.GregorianCalendar[time=1598150951138,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=29,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=7,WEEK_OF_YEAR=35,WEEK_OF_MONTH=5,DAY_OF_MONTH=23,DAY_OF_YEAR=236,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=4,AM_PM=0,HOUR=10,HOUR_OF_DAY=10,MINUTE=49,SECOND=11,MILLISECOND=138,ZONE_OFFSET=28800000,DST_OFFSET=0]
获取配置文件中bean的几种方式
Spring的配置文件是一个xml文件,我们可以自定义名字,一般使用applicationContext.xml作为配置文件名。
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:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 定义bean对象 -->
<bean id="stu" class="enity.Student">
<bean id="pho" class="enity.Phone">
<property name="brand" value="Huawei"></property>
<property name="system" value="android"></property>
<property name="memory" value="64G"></property>
</bean>
</beans>
Student.java
package enity;
public class Student {
private String name;
//无参构造函数
public Student() {
System.out.println("初始化");
}
//定义get方法
public String getName() {
return name;
}
//定义set方法
public void setName(String name) {
this.name = name;
}
//重写toString方法
@Override
public String toString() {
return "学生的名字是 " + name ;
}
}
通过配置文件中的id获取
TestSpring.java
public class TestSpringIOC {
@Test
public void test02(){
//指定配置文件对象ac
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
//通过ac创建指定的bean对象,并命名为stu
Object stu= ac.getBean("stu");
//打印出这个对象
System.out.println(stu);
}
}
通过bean类型获取
从 IOC 容器中获取 bean 时,除了通过 id 值获取,还可以通过 bean 的类型获取。但如 果同一个类型的 bean 在 XML 文件中配置了多个,则获取时会抛出异常,所以同一个类 型的 bean 在容器中必须是唯一的。
TestSpring.java
public class TestSpringIOC {
@Test
public void test02(){
//指定配置文件对象ac
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
//通过ac创建指定的bean对象,并命名为stu
Object stu= ac.getBean(Student.class);
//打印出这个对象
System.out.println(stu);
}
}
给 bean 的属性赋值
我就以自己的手机的配置来演示一下
通过getting、setting来赋值
通过getting、setting给bean的属性赋值是常用的方法。
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:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 定义bean对象 -->
<bean id="pho" class="enity.Phone">
<property name="brand" value="Huawei"></property>
<property name="system" value="android"></property>
<property name="memory" value="64G"></property>
</bean>
</beans>
TestSpring.java
public class TestSpring {
@Test
public void test03(){
Object pho= ac.getBean("pho");
//Object pho= ac.getBean(Phone.class);
System.out.println(pho);
}
}
Phone.java
package enity;
public class Phone {
private String brand;
private String system;
private String memory;
public void setBrand(String brand) {
this.brand = brand;
}
public void setSystem(String system) {
this.system = system;
}
public void setMemory(String memory) {
this.memory = memory;
}
@Override
public String toString() {
return "brand="+brand+"\n"+"system="+system+"\n"+"memory="+memory;
}
}
样例输出
brand=Huawei
system=android
memory=64G
通过自动匹配构造函数来赋值
通过自动匹配构造函数的方式来赋值,要考虑到参数的顺序和参数的个数,如果想要指定赋值的顺序,请加上index属性。
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:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 定义bean对象 -->
<bean id="pho" class="enity.Phone">
<constructor-arg value="HuaWei" />
<constructor-arg value="android" />
<constructor-arg value="64G" />
</bean>
<bean id="pho1" class="enity.Phone">
<constructor-arg value="Iphone" />
<constructor-arg value="IOS" />
</bean>
<bean id="pho2" class="enity.Phone">
<constructor-arg value="Samsung" />
</bean>
</beans>
Phone.java
package enity;
public class Phone {
private String brand ;
private String system ;
private String memory ;
//无参构造函数
public Phone() {
}
//含三个参数的构造函数
public Phone(String brand,String system,String memory) {
this.brand=brand;
this.system=system;
this.memory=memory;
}
//含两个参数的构造函数
public Phone(String brand,String system) {
this.brand=brand;
this.system=system;
}
//含一个参数的构造函数
public Phone(String brand) {
this.brand=brand;
}
@Override
public String toString() {
return "brand="+brand+"\n"+"system="+system+"\n"+"memory="+memory;
}
}
TestSpring.java
Juint测试类
public class TestSpring {
@Test
public void test04(){
Object pho= ac.getBean("pho");
//Object pho= ac.getBean(Phone.class);
System.out.println(pho);
}
@Test
public void test05(){
Object pho= ac.getBean("pho1");
//Object pho= ac.getBean(Phone.class);
System.out.println(pho1);
}
@Test
public void test06(){
Object pho= ac.getBean("pho2");
//Object pho= ac.getBean(Phone.class);
System.out.println(pho2);
}
}
样例输出
test04
brand=Huawei
system=android
memory=64G
test05
brand=Iphone
system=IOS
test06
brand=Samsung
你可能会问:如果参数不够,会不会报错?
答案是:当然不会,因为当你不给bean的属性赋值时,在创建的时候bean的属性都是默认为null的,如果你赋值的个数不够,那么那些没有赋值的属性就为空,如下图。

通过index来指定赋值顺序
只需要在applicationContext.xml文件bean中的constructor-arg加入index,例如
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:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 定义bean对象 -->
<bean id="pho" class="enity.Phone">
<constructor-arg value="HuaWei" index="2"/>
<constructor-arg value="android" index="1"/>
<constructor-arg value="64G" index="0"/>
</bean>
<bean id="pho1" class="enity.Phone">
<constructor-arg value="Iphone" />
<constructor-arg value="IOS" />
</bean>
<bean id="pho2" class="enity.Phone">
<constructor-arg value="Samsung" />
</bean>
</beans>
样例输出
之前的test04就会变为下面这样
brand=64G
system=android
memory=Huawei
通过type来区分重载的构造器
只需要在applicationContext.xml文件bean中的constructor-arg加入type
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:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 定义bean对象 -->
<bean id="pho" class="enity.Phone">
<constructor-arg value="HuaWei" index="0" type="java.lang.String"/>
<constructor-arg value="android" index="1" type="java.lang.String"/>
<constructor-arg value="64" index="2" type="java.lang.Integer"/>
</bean>
</beans>
type要和属性的类型相匹配,如果我不修改之前的Phone.java,会报错,内容如下
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pho' defined in class path resource [applicationContext.xml]: Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)
大概意思就是无法解析需要匹配的构造函数
所以我们要修改Phone.java中memory的类型
修改后如下
package enity;
public class Phone {
private String brand;
private String system;
private Integer memory;
public Phone() {
}
public Phone(String brand,String system,Integer memory) {
this.brand=brand;
this.system=system;
this.memory=memory;
}
@Override
public String toString() {
return "brand="+brand+"\n"+"system="+system+"\n"+"memory="+memory;
}
}
样例输出
brand=HuaWei
system=android
memory=64
3302



被折叠的 条评论
为什么被折叠?



