Spring
学习路线
- Spring 的第一天:Spring 的IOC的入门,Spring整合web项目
- Spring的第二天:IOC的注解开发,Spring的AOP的xml开发
- Spring的第三天:Spring的Aop的注解开发,Spring的事务管理
- ssh 的整合
Spring的概述
什么是Spring
Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson创建,简单来说,Spring是一个分层的javaEE/EEfull-stack(一站式) 轻量级开源框架
- Spring是SE/EE的一站式框架:Spring有EE开发中每一层解决的方案。
- EE的三层结构:
- WEB层:Spring MVC
- 业务层:Spring的Bean管理,声明式事务
- 持久层:Spring的JDBC的模板,Spring的ORM模块
Spring的优点:
Spring的版本
Spring3.X Spring4.X
Spring的IOC的入门
IOC(Inversion of Control)
IOC:控制反转,将对象的创建权反转给Spring。
- 解决程序的耦合性
Spring的入门
- 第一步:下载Spring的开发包
- 官网: spring 下载
spring-framework-4.2.4.RELEASE-dist.zip
- 解压:Spring的开发包
- docs
- libs
- schema
- 官网: spring 下载
第二:导包:只需要导红色圈里的那几个就行,还有log4j的一个包,跟一个日志的接口包commons-logging
第三:编写接口跟实现类
public interface UserDao {
public void sayHello();
}
public class UserDaoImpl implements UserDao {
@Override
public void sayHello() {
System.out.println("Hello Spring Demo1...");
}
}
- 第四:创建一个Spring的核心配置文件:
- 在src下创建
applicationContext.xml
名字可以变 - 引入约束
- 在src下创建
//约束在spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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">
.............................
</beans>
- 编写Spring配置文件
<bean id="userDao" class="路径"></bean>
- 第五:编写测试类
//Spring的方式:IOC的底层实现:工厂+反射+配置文件
public void demo2(){
ApplicationContext addli= new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=(UserDao) appli.getBean("userDao");;
userDao.sayHello();
}
DI
DI:依赖注入。需要有IOC的环境
- IOC和DI的区别:
- IOC:控制反转:将对象的创建权交给Spring
- DI:Spring在创建过程中,将类依赖的属性注入进来
//现在要配置的类中创建属性,并提供set方法
//然后再在配置文件中配置
<bean id="UserDao" class="UserDao路劲">
//注入属性
<property name="name" value="李四"/>
</bean>
Spring的工厂类的概述
BeanFactory
BeanFactory
是Spring 早期的工厂类,现在已经不用了- BeanFactory在调用
getBean()
的时候才会创建类的实例。
ApplicationContext
- ApplicationContext是Spring目前使用的工厂类
- ApplicationContext支持比BeanFactory更加强大的功能(国际化)
ApplicationContext在加载Spring的配置文件的时候,就会创建类的实例
在
ApplicationContext
下有两个实例:ClassPathXmlApplicationContext
:加载类路劲下的配置文件FileSystemXmlAppliocationContext
:加载本地硬盘上的配置文件
Spring的常见的配置
<bean id="" class="" scope="" init-method="方法名" destory-method="方法名" />
- 后边的两个可以省略
Id和name的配置
- id:用到了唯一的约束,都不要使用相同名称的值。Id中不能使用特殊字符
- name:没有使用唯一的约束,都不要使用相同名称的值。name中可以使用特殊字符。
- id跟name中如果有相同的值,运行时会报错。
在Struts1框架中,Action交给Spring管理
<bean name="/login" class="xxx">
因为有/
所以只能用name。
scope的配置:Bean作用范围
- singleton :默认值,单例的,在一个方法中不管创建多少次,都是同一个对象。
- prototype :多例的。
- request :在Web项目中使用,创建一个类,保存到request域中。
- session :在web项目中使用,创建一个类,保存到session中。
- globalsession:在web项目中使用,而且
Prolet
环境,就是例如登陆了百度,就能访问百度云啊贴吧啊什么的。
bean的生命周期的配置(可以省略)
初始化方法跟销毁方法都是要在UserDao类中定义的。
- init-method=”方法名” :Bean被创建的时候要去执行的方法
- destory-method=”方法名” :Bean被销毁的时候要去执行的方法
- Bean 的创建必须是单例的,而且必须是关闭工厂
ClassPathXmlApplicationContext对象.close()
- Bean 的创建必须是单例的,而且必须是关闭工厂
配置不联网提示
- windows属性 —> xml catalog —> 约束中的最后一个地址复制过来到
key
,上面选择本地中的spring-framework-4.2.4.RELEASE\schema\beans\4.2
的那个,中间选择key type
为Schema location
Spring的Bean管理的xml的方式
Spring的Bean的创建
Spring中提供了三种Bean的实例化的方式:
- 无参构造的方式
//bean类
public class bean{
public bean(){
syso("无参构造被调用");
}
}
//配置文件
<bean id="bean" class="bean的地址">
- 静态工厂实例化的方式
//bean类
public class bean{
}
//静态工厂类
public class beanFactory{
public static Bean createBean(){
syso("静态工厂执行了");
return new Bean();
}
}
//配置文件
<bean id="bean" class="beanFactory的地址" factory-method="createBean">
- 实例工厂实例化的方式
//bean类
public class bean{
}
//实例工厂类
public class beanFactory{
public Bean createBean(){
syso("实例工厂执行了");
return new Bean();
}
}
//配置文件
<bean id="beanFactory" class="beanFactory的地址" />
<bean id="bean" factory-bean="beanFactory" factory-method="createBean" />
Bean的属性注入
Bean的属性注入
-
- 构造方法的方式
-
- set方法的属性注入
-
- 接口注入的方式
public interface Injection{
public void setUsername(String username);
}
class User implements Injection{
private String username;
public void setUsername(String username){
this.username=username;
}
}
Spring的Bean的属性注入
Spring 中只支持前两种:
- 构造函数:
//配置文件,当然前提是有这个实体类跟有参构造函数
<bean id="car" class="car的路劲" >
<constructor-arg name="" value="" />
<constructor-arg name="" value="" />
</bean>
//构造注入中的<constructor-args name="">
name也可以换为index,从0开始表示第一个构造方法中的值是什么
- set方法
//配置文件,当然前提是有这个实体类跟set方法
<bean id="car2" class="com.itheima.spring.demo4.Car2">
<property name="name" value="宝马/>
<property name="price" value="800000"/>
</bean>
- set中如果有对象的话
<bean id="people" class="people的路劲" >
<constructor-arg name="正常的属性名" value="正常的属性值" />
<constructor-arg name="正常的属性名" ref="前面配置文件的id这里用car" />
</bean>
Spring2.5版本之后提供p名称空间的属性注入
- 引入p名称空间:
xmlns:p="http://www.springframework.org/schema/p"
- 完成属性注入:
- 格式:
- 普通属性 p:属性名=“属性值”
- 对象类型的属性 p:属性名-ref=“其他属性的id或name”
- 格式:
//普通
<bean id="car" class="car路劲" p:name="" p:price="" />
//对象类型的
<bean id="people" class="people的路劲" p:name="" p:car-ref="car" />
Spring3.X版本之后提供的 spEL 的属性注入:
- spEL:Spring Expression Language
- /#{}
//普通类型
<bean id="car" class="">
<property name="name" value="#{'奔驰'}">
<property name="price" value="#{123}">
</bean>
//对象类型
<bean id="employee" class="">
<property name="name" value="#{'强强'}">
<property name="car" value="#{car}">
</bean>
- 还能用另外一个类的属性或方法名来赋值,先创建这个类,要用属性的话,可以直接写get方法,不用定义成员变量的。
- 要想用哪个类中的方法,就得先实例化这个类
- 然后再 #{实例化类名.属性/方法} 就可以了
//定义要使用的类
public class CarInfo {
//public String name;
public String getName() {
return "奔驰";
}
public Double calculatePrice(){
return Math.PI * 100000;
}
}
复杂类型的属性注入
list map propertise 等复杂的属性类型
- list/数组
//如果list的是对象最里边可以用<ref/>
<bean id="" class="" >
<property name="lists">
<list>
<value>值</value>
<value>值</value>
<value>值</value>
<list>
</property>
</bean>
- map
//如果map里边是对象<entry key-ref="" value-ref=""/>
<bean id="" class="" >
<property name="maps">
<map>
<entry key="" value="" />
<map>
</property>
</bean>
map还有一种方式
需要生成set方法,并在map标签中添加 <entry> <key> <value>test1</value> </key> <value>AAA</value> </entry>
- propertise,键值对的形式
<bean id="" class="" >
<property name="props">
<props>
<props key="">值</props>
<props>
</property>
</bean>
Spring的分模块开发
就是可能有两个配置文件,分别配置不同的类
- 可以在加载配置文件时加载两个配置文件,用
,
隔开 - 也可以只加载一个配置文件,然后在其中引入另外一个配置文件
<import resource="applicationContext2.xml">
- 如果引入的配置文件中的id有跟原配置文件的id相同的值,则会覆盖原来的。
案例中出现的问题
将Dao配置到Spring
- 可以在配置service方法的时候把,Dao当作一个属性来配置,先把customerDao实例化,然后再引入到service配置文件中:
<bean id="customerService" class="com.itheima.crm.service.impl.CustomerServiceImpl">
<property name="customerDao" ref="customerDao"/>
</bean>
<bean id="customerDao" class="com.itheima.crm.dao.impl.CustomerDaoImpl">
</bean>
配置监听器,使每次获取的都是同一个工厂类
- 为了避免每次用的时候,都创建一个工厂类,用监听器,在服务器启动的时候就让创建了工厂了,并存在ServletContext中,以后直接用就行
- 先引一个Spring的jar包:
spring-web-4.2.4.RELEASE.jar
- 包中已经配好了监听器,直接配置就行:
- 先引一个Spring的jar包:
在web下配置监听器
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
//让上面那个监听器去加载下边的这个配置文件
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
获得工厂:
//保存客户的方法:save
public String save(){
//调用业务层,使用包中封装好的工具类获得servletContext中的工厂类
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext_());
CustomerService customerService = (CustomerService) applicationContext.getBean("customerService");
customerService.save(customer);
return NONE;
}