Spring是什么
开源的,用来简化企业级应用开发的应用开发框架。
简化开发: Spring框架对常用的api都做了封装,比如:对jdbc就做了一套 封装(Spring Jdbc),使用SpringJdbc访问数据库, 就不再需要考虑如 何获取连接与关闭连接等操作了。
解耦: Spring帮我们管理对象之间的依赖关系(对象之间的耦合度降低了), 这样软件的维护性得到提高。
集成其它框架:Spring可以很好地和其它的一些框架进行集成,这样,使用 这些框架就更方便了。
Spring容器
(1)什么是Spring容器?
Spring框架中的一个核心模块,用来管理对象。
注:
管理对象:对象的创建、销毁、初始化等等操作,以及对象之间的依赖关系。
(2)如何启动Spring容器?
step1.导包。
在pom文件中
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
step2.添加Spring配置文件。
配置一个xml文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:jdbc="http://www.springframework.org/schema/jdbc" 6 xmlns:jee="http://www.springframework.org/schema/jee" 7 xmlns:tx="http://www.springframework.org/schema/tx" 8 xmlns:aop="http://www.springframework.org/schema/aop" 9 xmlns:mvc="http://www.springframework.org/schema/mvc" 10 xmlns:util="http://www.springframework.org/schema/util" 11 xmlns:jpa="http://www.springframework.org/schema/data/jpa" 12 xsi:schemaLocation=" 13 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 14 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 15 http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd 16 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd 17 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 18 http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd 19 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 20 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 21 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> 22 23 24 </beans>
step3.启动容器。
String config = "applicationContext.xml";//字符串为Spring配置文件的全名 /** * ApplicationContext接口(声明了容器的一些方法) * ClassPathXmlApplicationContext类(实现了上述接口, * 该类会依据类路径去查找配置文件然后启动容器) */ ApplicationContext ac = new ClassPathXmlApplicationContext(config);
(3)如何创建对象?
1)方式一 无参构造器
step1.为类添加无参构造器或者直接使用缺省构造器。
step2.在配置文件当中,添加bean元素。
<bean id="" class=""/>
bean指的是有容器管理的对象,id:要求唯一(注早期版本用的是name),class:要求写类的完整名字(全限类名)
<!-- 使用无参构造器来创建对象 -->
<bean id="apple" class="first.Apple"/>
step3.启动容器,调用容器提供的一个方法(getBean)。
/**
* getBean方法的第一个参数时bean的id或者时bean的name,
* 第二个方法
*/
Apple A = ac.getBean("apple", Apple.class);
2) 方式二 静态工厂方法
<!-- 使用静态工厂方法创建对象 factory-method:指定一个静态方法(容器会调用该类的这个静态方法来创 建对象)= 相当于:Calender c = Clender.getInstance()--> <bean id="ca" class="java.util.Calendar"factory-method="getInstance"/>
3) 方式三 实例工厂方法
<!-- 使用实例工厂方法创建对象, actory-method:指定一个实例方法(容器会调用该实例的指定方法来创建对象) factory-bean:指定要调用的对象的id 相当于:调用了GregorianCalendar对象的getTime方法 --> <bean id="time" factory-bean="ca" factory-method="getTime"/>
(4)作用域(scope)
1)默认情况下(默认作用于为singleton),对于某个bean元素,容器只会创 建一个实例。
<bean id="bs" class="basic.ScopeBean" scope="singleton"/>
ScopeBean sc1 = ac.getBean("bs", ScopeBean.class);
ScopeBean sc2 = ac.getBean("bs", ScopeBean.class);
System.out.println(sc1==sc2);//------true-----
2)如果将作用域设置为"prototype",容器会创建多个实例。
<bean id="bs" class="basic.ScopeBean" scope="prototype"/>
ScopeBean sc1 = ac.getBean("bs", ScopeBean.class);
ScopeBean sc2 = ac.getBean("bs", ScopeBean.class);
System.out.println(sc1==sc2);//------false-------
(5)生命周期相关的两个方法
1)初始化
使用init-method属性指定初始化方法。
2)销毁
使用destroy-method属性指定销毁方法。
注意:只有作用域为singleton时,销毁方法才会执行。
<!--
init-method:指定初始化方法名
destroy-method:指定销毁方法名
注意:只有作用域为singleton(单例),销毁方法才会执行,
-->
<bean id="mb1" class="basic.MessageBean" init-method="init"
destroy-method="destroy" scope="prototype"/>
(6)延迟加载(lazy-init)
1)默认情况下(lazy-init=”true”)
容器启动之后,会将所有作用域为singleton的bean先创建好。
<!-- lazy-init:如果值为true,表示延迟加载 -->
<bean id="sb1" class="basic.ScopeBean" lazy-init="true"/>
2)开启延迟加载后(lazy-init=”false”)
容器启动之后,对于作用域为singleton的bean,不再创建(当调用getBean 方法时才会创建)
IOC和DI
1)什么是IOC (Inversion Of Controll 控制反转)?
对象之间的依赖关系由容器来建立。
2)什么是DI(Dependency Injection 依赖注入)?
容器通过调用set方法或者构造器来建立对象之间的依赖关系。
注:
IOC是目标,DI是手段。

3)依赖注入的两种方式
方式一 set方法注入
step1. 添加set方法(在要注入的类中添加)。
step2. 在配置文件当中,使用<property>来配置set方法注入。
step3. 启动容器,调用getBean方法。

方式二 构造器注入
step1. 添加相应的构造器
step2. 在配置文件当中,使用<constructor-arg>来配置构造器注入。
step3. 启动容器,调用getBean方法。

4) 自动装配
在配置文件当中,不用告诉容器采用哪种注入方式也不用告诉容器被注入的 bean的id,有容器依据某些规则,自动建立对象之间的依赖关系,通过byName时被注入的id必须与注入的set方法名字一致
a.容器默认情况下,是不会自动装配的。
b.可以让容器依据某些规则,自动建立对象之间的依赖关系
(仍然需要调用set方法或者构造器)。
注:自动装配建议少用(配置文件虽然简化了,但可读性变差,而且容易出错),如果要使用,建议使用byName。

值的注入
注入基本类型的值
使用value属性
name与方法中对象的名一致,value的值的类型与对象的类型一致
<bean id="teacher" class="value.Teacher"> <property name="name" value="Hille"/> <property name="age" value="85"/> </bean>
注入集合类型的值
1) 方式一 直接注入
注入List(值可以重复):
<!-- 注入集合类型的值 -->
<property name="interest">
<list>
<value>吃饭</value>
<value>睡觉</value>
<value>敲代码</value>
</list>
</property>
注入set:(值不能重复,如果有重复的值,只会注入一个)
<property name="city">
<set>
<value>北京</value>
<value>郑州</value>
<value>广州</value>
</set>
</property>
注入map的值:(key的值不能重复,如果重复,后一个会把前一个的的value给顶掉)
<property name="score">
<map>
<entry key="英语" value="50"/>
<entry key="语文" value="60"/>
<entry key="数学" value="70"/>
<entry key="生物" value="80"/>
<entry key="化学" value="90"/>
</map>
</property>
注入Property的值:
<property name="db">
<props>
<prop key="username">Sally</prop>
<prop key="password">123456</prop>
</props>
</property>
2) 方式二 引用的方式注入
注入List

注入set
<util:set id="cityBean">
<value>北京</value>
<value>郑州</value>
<value>广州</value>
<value>广州</value>
</util:set>
<bean id="t2" class="value.Teacher">
<property name="city" ref="cityBean"/>
</bean>
注入map
<util:map id="scoreBean">
<entry key="英语" value="50"/>
<entry key="语文" value="60"/>
<entry key="数学" value="70"/>
<entry key="生物" value="80"/>
<entry key="化学" value="90"/>
</util:map>
<bean id="t2" class="value.Teacher">
<property name="score" ref="scoreBean"/>
</bean>
注入properties
<util:properties id="dbBean">
<prop key="username">Sally</prop>
<prop key="password">123456</prop>
</util:properties>
<bean id="t2" class="value.Teacher">
<property name="db" ref="dbBean"/>
</bean>
读取properties文件

<bean id="t2" class="value.Teacher">
<property name="db" ref="config"/>
</bean>
ClassPathXmlApplicationContext cptx = new ClassPathXmlApplicationContext("value.xml"); Properties p = cptx.getBean("config", Properties.class); System.out.println(p);
Spring表达式
读取bean的属性值或者读取集合类型的
<bean id="stu1" class="value.Teacher"><!-- 这个方法中必须有对应的get方法 -->
<property name="name" value="Hille"/>
<property name="interest">
<list>
<value>吃饭</value>
<value>睡觉</value>
</list>
</property>
<property name="score">
<map>
<entry key="英语" value="50"/>
<entry key="语文" value="60"/>
</map>
</property>
</bean>

<!-- config为properties文件的文件名,如果文件中的key为xxx.xxx,中间有点号时时必须用[‘xxx.xxx’] 如果key为xxx中间没有点时可以用config.xxx也可也用上面那种 -->
使用注解简化配置文件
(1)组件扫描
1)什么是组件扫描?
容器会扫描base-package指定的包及其子包
下面所有的类,如果该类前面有一些特定的注解
(比如 @Component),则纳入容器进行管理(相当于
在配置文件当中有一个对应的bean元素一样)。
2)编程步骤
step1.在类前面添加一些特定的注解。
@Component 通用。
@Repository 持久层。
@Service 业务层。
@Controller 控制层。
step2.在配置文件当中,配置组件扫描。

(2)几个注解

(3)依赖注入相关的几个注解
1)@Autowired @Qualifier
a.支持set方法注入


b.支持构造器注入

2)@Resource(只支持set方法注入)(将该注解添加到set方法之前,或者也可以直接添加到属性前,name属性用来指定被注入bean的id)

3)@Value(放在set方法前会调用set方法,放在值前直接注入)

来源:https://www.cnblogs.com/mengguozhihou/p/7805465.html