Spring简介
分层的,full-stack的轻量级开源框架
Spring两大核心
- IoC控制反转 (反转的是对象的创建权) 最大的优点是解耦合
- AOP面向切面编程 底层实现是动态代理 作用:程序方法在不修改的情况下进行增强
Spring的各个层的解决方案:
- web层: SpringMVC
- service层 :
- DAO层:
- spring JDBC Templae(类似DBUtils)
- Spring Data JPA\Redis\Solr\ES等
Spring的优势
- 方便解耦 简化开发
- AOP编程的支持
- 声明式事务控制
声明式:与之对应的是编程式 : XML和注解都称为声明
- 方便程序的测试
- 方便集成各种优秀框架
- 降低JavaEE的API的使用难度(封装)
Spring的发展
- Spring Boot (轻代码 轻配置)
- Spring Security 安全框架
- Spring Cloud 用于分布式开发
Spring快速入门(IoC:让Spring框架创建Bean对象)
- 导入Spring相关jar包
- 导入核心容器的4个jar: beans, core, context, expression
- 框架会访问日志文件,导入日志相关API: apache-commons-logging.jar
- 开发中习惯让logging去继承log4j ,自动集成 5.
- 创建bean
- 创建xml
- 测试
配置文件的配置
配置文件放在src目录下,自己可以起名字,但是一般都是使用applicationContext.xml
0.导入约束
约束的位置在压缩包
spring-framework-4.2.4.RELEASE/docs/spring-framework-reference/html/xsd-configuration.html
约束为
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns=http://www.springframework.org/schema/beans ①
xsi:schemaLocation="http://www.springframework.org/schema/beans ② http://www.springframework.org/schema/beans/spring-beans-3.2.xsd ③">
① Xmlns(XML NameSpace) 声明命名空间,建议是用网址做命名空间,但并不会去访问改网址, 仅仅是 namespace 和 xsd(xsd 是 spring 这个 xml 的 schema 文件,里面定义配置内容)里 声明的 targetNamespace 保持一致 . 注:这里命名空间是改不了的,其实是在代码中也写死了,可以打开 spring-beans3.2.0.M1-sources.jar 包的 org\springframework\beans\factory\xml\BeanDefinitionParserDelegate.java 查看对 http://www.springframework.org/schema/beans这个namespace的定义。
② schemaLoacation .用于绑定命名空间的 schema 文件,通常是用 URL 值对,中间用空格隔 开,前面 URL 是命名空间,后面 URL 为 schema 的文件地址
③ xsd 的存放地址,如果没有声明,eclipse 会去网上下载.
1.基本配置
使用bean标签进行配置,和以前三层架构解耦合用的BeanFactory差不多,只有”暱称”和路径
- id:bean的实例,在spring容器中一个唯一的标识
- class:bean的全限定名
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>
2.Bean标签中scope的配置
scope的选择:
- singleton(默认值):单例
- prototype:原形 多例
需要注意的是,单例模式下,配置文件被加载,spring容器创建的时候,Bean对象就被创建了;而在多例模式下,在调用getBean的方法的时候,Bean对象才被创建
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" scope="prototype"></bean>
3.Bean生命周期相关的方法配置
也是Bean标签中的属性
- init-method:指定Bean初始化的时候,执行的方法
- destroy-mothod:指定Bean销毁时执行的方法
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
通过这两个属性的设置,Bean中任何一个方法,都可以充当初始化方法,或销毁方法
单例对象生命周期归容器管理
多例归JVM垃圾回收机制管理
4.Bean实例化的三种方式
1.通过Bean无参构造创建对象(以上例子都是通过该方式创建的,也是最常用的方法)
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>
2.通过静态工厂的方式创建对象
如果一个Bean可以通过一个工厂的某个方法获得,name我们可以使用静态工厂的方式获取它
它有三个属性 id–>和以前一样,用来标识这个Bean; class–>这个class是工厂的位置,因为这个模式是通过工厂获取的Bean; method–>标识出具体哪一个方法用来生成我们想要的Bean
<bean id="userDao" class="com.cuixiaoming.factory.StaticBeanFactory" factory-method="getUserDao"></bean>
3.通过实例工厂的方式创建对象
这个和上一个的区别是,这种方法中,工厂Bean已经被配置到了spring容器中,所以我们不需要用class标识出工厂的位置,我们是用另一个属性factory-bean
,标上工厂的id即可
<bean id="beanFactory" class="com.cuixiaoming.factory.InstanceBeanFactory"></bean>
<bean id="userDao" factory-bean="beanFactory" factory-method="getUserDao"></bean>
经过测试我发现,这两个工厂的方式的时候,当spring容器加载的时候,factory-method
标注的方法都会执行一次,然后等到每次创建对象的时候,又会执行;
5.依赖注入(DI)的设置
注入之前,要在被注入的Bean中将注入的东西设为私有变量,并且提供set方法
property标签(位于Bean标签内)
- name: 是该实体的set方法的属性名称
- ref: 代表引用的id 引用容器中的那一个bean
- value: 注入普通字符串
- list: 注入list集合
- map: 注入map集合
- props: 注入props集合
1.注入Bean
我们用最基本的形式,要想执行dao层方法,需要先获得service对象,然后service对象再获得dao层对象,从而执行dao层方法,也就是说,需要在spring容器中获取两次;
如果,我们通过注入,将dao层对象注入到service对象中,我们在获得service对象的时候,就能一起获取到dao层对象,如下图所示;
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao" ></property>
</bean>
2.注入普通字符串
将一个字符串设为私有变量,并提供名为setStr()的set方法,这样我们创建对象的时候,它里面已经包含这个字符串变量了;
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
<property name="str" value="这是一个value"></property>
</bean>
3.注入集合
注入集合是非常重要的知识点
一般来说,也是先设置成私有变量并提供set方法;然后在property中写个name,然后在标签内部写集合标签
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
<!-- list集合的注入 -->
<property name="strList" >
<list>
<value>第一个</value>
<value>第二个</value>
<value>第三个</value>
</list>
</property>
<!-- map集合的注入,里面两个user放在最下面了 -->
<property name="userMap">
<map>
<entry key="user1" value-ref="user1"></entry>
<entry key="user1" value-ref="user2"></entry>
</map>
</property>
<!-- property集合的注入-->
<property name="prop">
<props>
<prop key="p1">123</prop>
<prop key="p2">456</prop>
<prop key="p3">789</prop>
</props>
</property>
</bean>
<!-- map集合里面的两个user -->
<bean id="user1" class="com.cuixiaoming.domain.User">
<property name="username" value="张三"></property>
<property name="age" value="23"></property>
</bean><bean id="user2" class="com.cuixiaoming.domain.User">
<property name="username" value="李四"></property>
<property name="age" value="24"></property>
</bean>
6.属性注入的三种方式
1.set注入
上面这些方式都是采用的set注入,就是在被注入的Bean里面,将注入的东西提取私有,提供set方法,不再赘述
2.有参构造注入
通过被注入的Bean提供有参和无参构造,(这种注入不使用无参构造,但是没有无参构造会导致其他功能不能使用,一般来说,只要给出有参构造,就要同时给出无参构造)
public UserDaoImpl() {
System.out.println("dao层无参构造执行了");
}
public UserDaoImpl(String username,User user) {
System.out.println("dao层有参构造执行了");
System.out.println("username="+username);
System.out.println("user=" +user);
}
配置文件
在Bean标签里面使用constructor-arg标签,这个标签可以使用键值,也可以继续注入其他Bean
<bean id="user1" class="com.cuixiaoming.domain.User">
<property name="username" value="张三"></property>
<property name="age" value="23"></property>
</bean>
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl">
<constructor-arg name="username" value="奥特曼"></constructor-arg>
<constructor-arg name="user" ref="user1"></constructor-arg>
</bean>
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
需要注意的是,你的bean中constructor-arg的数据要至少和一个构造方法所有参数吻合,不然会报错
3.p命名空间注入
这个方法也是使用set方法进行的注入,不过,语法非常简单
首先,在约束上面加上这一句,就是把第一个约束复制改一下
<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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
可以看出,它可以替代所有的set注入,而且语句极其简单
<bean id="user1" class="com.cuixiaoming.domain.User" p:username="张三" p:age="23"></bean>
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" p:str="这是一个字符串" p:user-ref="user1"></bean>
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>
7.导入其他的配置文件
这个是用于分布式开发,把多个配置文件合成一个
使用下面这个标签即可
<import resource=""/>