spring框架概述
1 spring框架概述
1.1 什么是spring
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson开发。
它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架
dao(JdbcTemplate) service(spring控制事务) web(springmvc)
Spring的核心是控制反转(IoC)和面向切面(AOP)。
简单来说,Spring是一个分层的JavaSE/EE full-stack 轻量级开源框架。 1)IoC 和DI 2)AOP
一句话描述spring:full-stack 轻量级开源框架
分层: full-stack,每一个层都提供解决方案
web层:struts,spring-MVC
service层:spring 事务控制 spring
dao层:hibernate,mybatis , jdbcTemplate(spring提供了一个模板对象) --> spring-data
ssh:struts2+spring+hibernate(以前的了解一下)
ssm:spring+springmvc+mybatis(现阶段常用)
1.2 spring核心
Spring的核心是控制反转(IoC)和面向切面(AOP)
1.3 spring优点
1. 方便解耦,简化开发 (高内聚低耦合)
面试题:spring的IoC(控制反转)底层用到什么设计模式?-- 静态工厂模式 2. AOP编程的支持
3. 声明式事务的支持 (AOP 动态代理)
4. 方便程序的测试
5. 方便集成各种优秀框架 *****
6. 降低JavaEE API的使用难度 EJB
|
1.4 spring体系结构
核心容器:beans、core、context、expression
dao service 对象的创建 交给spring
2 入门案例:IoC【掌握】
2.1 导入jar包
4 + 1 : 4个核心(beans、core、context、expression) + 1个依赖(commons-loggins...jar)
2.2 目标类
1. 提供UserService接口和实现类
2. 获得UserService实现类的实例
之前开发中,直接new一个对象即可。
UsersService service = new UsersServiceImpl();
学习spring之后,将由Spring创建对象实例--> IoC 控制反转(Inverse of Control)
之后需要实例对象时,从spring工厂(容器)中获得,需要将实现类的全限定名称配置到xml文件中
把创建对象的过程交给spring来创建,IoC
2.3 配置文件
1. 位置:任意,开发中一般在classpath下(src)
2. 名称:任意,开发中常用applicationContext.xml
不是必须的。
3. 内容:添加schema约束
约束文件位置:spring-framework-XXX.RELEASE\docs\spring-framework-reference\html\ xsd-config.html
<bean id="userService" name="us" class="com.itqf.service.impl.UserServiceImpl"></bean> |
2.4 测试
//创建ApplicationContext对象 ApplicationContext aContext=new ClassPathXmlApplicationContext("applicationContext.xml");
//根据spring的核心对象解析applicationContext.xml配置文件 从配置文件中获取一个UserService 对象 //从spring的配置文件中获取对象的三种方式 //方式一:根据对象的class UserService userService = aContext.getBean(UserService.class); //单词写错:NoSuchBeanDefinitionException: No bean named 'userService11' available UserService userService2 = (UserService) aContext.getBean("userService"); UserService userService3 = (UserService) aContext.getBean("us");
System.out.println(userService==userService2); |
3 DI案例【掌握】 依赖注入
1. DI Dependency Injection ,依赖注入
类与类之间的依赖关系,由spring通过spring注入 ---依赖注入
class B {
private A a = new A(); //B类依赖A类 Service依赖dao
}
依赖:一个对象需要使用另一个对象
注入:通过setter方法(或其他方式)进行另一个对象实例设置。
class B {
private A a ;//B类依赖A类 Service依赖dao
}
a对象由spring通过setter方法注入
2. 例如:练习
class BookServiceImpl{
//之前开发:接口 = 实现类 (service和dao耦合)
//private BookDao bookDao = new BookDaoImpl();
//spring之后 (解耦:service实现类使用dao接口,不知道具体的实现类)
private BookDao bookDao;
setter方法
}
模拟spring执行过程
创建service实例:BookService bookService = new BookServiceImpl() -->IoC <bean>
创建dao实例:BookDao bookDao = new BookDaoImple() -->IoC
将dao设置给service:bookService.setBookDao(bookDao); -->DI <property
IoC:把创建对象的过程交给了Spring (<bean ………………>)
DI:通过调用setXXX方法注入另外的对象 <property name=”” ref=””>
<!-- 1.dao 等价于: BookDao bookDao = new BookDaoImpl(); --> <bean id="bookDao" class="com.itqf.di.dao.impl.BookDaoImpl"></bean>
<!-- service 等价于: BookService bookService = new BookServiceImpl(); bookService.setBookDao(bookDao); --> <bean id="bookService" class="com.itqf.di.service.impl.BookServiceImpl"> <!-- 注入dao --> <property name="bookDao" ref="bookDao" ></property> </bean> |
4 schema xml提示
1. 步骤一:确定xsd文件位置
spring-framework-RELEASE\schema\beans
2. 步骤二:复制路径
3. 步骤三:搜索“xml catalog”
4. 步骤四:添加约束提示
5 核心API
1. api整体了解,之后不使用,在学习过程需要。
2. BeanFactory :这是一个工厂,用于生成任意bean。 创建对象
采取延迟加载,第一次getBean时才会初始化Bean
3. ApplicationContext:是BeanFactory的子接口,功能更强大。当配置文件被加载,就进行对象实例化。
ClassPathXmlApplicationContext 用于加载classpath(类路径、src)下的xml
加载xml运行时位置 --> /WEB-INF/classes/...xml
FileSystemXmlApplicationContext 用于加载指定盘符下的xml
加载xml运行时位置 --> /WEB-INF/...xml
通过java web ServletContext.getRealPath() 获得具体盘符
BeanFactory
FactoryBean 区别?
6 实例化Bean 基于XML
6.1 实例化方式
l 3种bean实例化方式:默认构造、静态工厂、实例工厂
6.1.1 默认构造(常用)
<bean id="" class=""> 必须提供默认构造 |
6.1.2 静态工厂
1. 常用与spring整合其他框架(工具)
2. 静态工厂:用于生成实例对象,所有的方法必须是static
<bean id="" class="工厂全限定类名" factory-method="静态方法"> |
编写静态工厂类
<bean id="userServiceId" class="工厂类对象全路径 " factory-method="createService"></bean>
6.1.3 实例工厂
1. 实例工厂:必须先有工厂实例对象,通过实例对象创建对象。提供所有的方法都是“非静态”的
普通的工厂类 (非静态方法).
<!-- 创建工厂实例 --> <bean id="myBeanFactoryId" class="工厂对象全路径 "></bean> <!-- 获得userservice * factory-bean 确定工厂实例 * factory-method 确定普通方法 --> <bean id="userServiceId" factory-bean="myBeanFactoryId" factory-method="createService"></bean>
|
7 作用域
面试:spring bean的作用域? / springBean的scope的取值?
作用域:用于确定spring创建bean实例个数
servlet:单例
struts2:action(处理请求):多例
面试题: struts2是线程安全还是不安全的?
安全的。
spring:bean:默认是单例
bean标签有scope属性可以设置bean的作用域。
取值:
singleton 单例,默认值。
prototype 多例,每执行一次getBean将获得一个实例。例如:struts整合spring,配置action多例。
面试题: 什么时候bean的作用域需要设计为多例的?
Ssh整合(或者struts2和spring整合时),action的创建交给spring创建,需要给bean设计为多例的。
配置信息
<bean id="" class="" scope=""> |
8 生命周期
8.1 初始化和销毁
l 目标方法执行前后执行后,将进行初始化或销毁。
<bean id="" class="" init-method="初始化方法名称" destroy-method="销毁的方法名称"> |
<bean id="userDao" name="userDao2" class="com.itqf.lifecycle.UserDao" init-method="init" destroy-method="destory"></bean> |
9 依赖注入
9.1 属性依赖注入
依赖注入方式:手动装配 和 自动装配
手动装配:一般进行配置信息都采用手动
基于xml装配:构造方法、setter方法 、 p标签注入
基于注解装配:@autowrired @resource
自动装配:
autowire="byName"
byType:按类型装配
byName:按名称装配
constructor构造装配,
auto: 不确定装配。
9.1.1 构造方法
<constructor-arg> 用于配置构造方法一个参数argument
name :参数的名称
value:设置普通数据
ref:引用数据,一般是另一个bean id值
index :参数的索引号,从0开始 。如果只有索引,匹配到了多个构造方法时,默认使用第一个。
type :确定参数类型
例如1:使用名称name
<constructor-arg name="username" value="jack"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
例如2:【类型type 和 索引 index】
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
9.1.2 setter方法
普通数据
<property name="" value="值"> 等效 <property name=""> <value>值</value>
|
引用数据
<property name="" ref="另一个bean"> 等效 <property name=""> <ref bean="另一个bean"/>
|
9.1.3 P命令空间[了解]
对“setter方法注入”进行简化,替换<property name="属性名">,而是在
<bean p:属性名="普通值" p:属性名-ref="引用值">
p命名空间使用前提,必须添加命名空间
<bean id="userService" class="com.itqf.bean.p.UserServiceImpl" p:userDao-ref="userDao" > </bean> <bean scope="prototype" id="userAction" class="com.itqf.bean.p.UserAction" p:userService-ref="userService"></bean>
|
9.1.4 集合注入
<bean id="myCollection" class="com.itqf.bean.collection.MyCollection" autowire="default"> <property name="name" value="天线宝宝"></property> <!-- 数组 --> <property name="arr"> <array> <value>张三</value> <value>lisi</value> <value>王苏</value> </array> </property> <!-- 集合 --> <property name="list"> <list> <value>basketball</value> <value>football</value> <value>pingpongball</value> </list> </property> <!-- set --> <property name="set"> <set> <value>宝马</value> <value>劳斯莱斯</value> <value>法拉利</value> <value>宾利</value> <value>QQ</value> </set> </property>
<!-- Map --> <property name="map"> <map> <entry> <key><value>1001</value></key> <value>张三</value> </entry> <entry> <key><value>1002</value></key> <value>李四</value> </entry> <entry> <key><value>1003</value></key> <value>赵六</value> </entry> </map> </property>
<!-- properties 类型 --> <property name="properties"> <props> <prop key="jdbc.driverClass">com.mysql.jdbc.Driver</prop> <prop key="jdbc.url">jdbc:mysql://localhost:3306/book</prop> </props> </property>
</bean>
|
10 使用注解(常用重点)
面试题:请说出spring常用的注解有哪些?
注解:就是一个类,使用@注解名称
开发中:使用注解 取代 xml配置文件。
1. @Component取代<bean class="">
@Component("id") 取代 <bean id="" class="">
2.web开发,提供3个@Component注解衍生注解(功能一样)取代<bean class="">
@Repository :dao层
@Service:service层
@Controller:web层
3.依赖注入,给私有字段设置,也可以给setter方法设置
引用值:
方式1:按照【类型】注入
@Autowired
private BookDao bookDao;
方式2:按照【名称】注入2
@Resource( name="名称")
eg:
@Resource( name="bookDao")
private BookDao bookDao; spring容器中找name为bookDao
方式3:按照类型注入(autowired)时,如果有两个匹配结果,会报错
可以使用如下解决方案:
@Qualifier("userServiceImpl2")
//@Autowired //按照类型注入 但是,如果找到多个匹配的就会报错,expected single matching bean but found 2 //@Qualifier("userServiceImpl2") //按照名称注入 |
注意:@Qualifier不能当独使用,一般配合autowired使用
//@Autowired 按照类型注入 //@Qualifier("userServiceImpl") //按照名称注入 @Resource(name="userServiceImpl") //按照名称注入 private UserService userService; |
//注入dao @Autowired //按照类型注入 public void setUserDao(UserDao userDao) { this.userDao = userDao; } |
创建对象:
四个:
@Componet
@Repository dao
@Service service
@Controller 控制层
注入:
@Autowired 按照类型注入 (spring提供)
@Qulifer() 配合Autowired 使用(用的少)
@Resource() 按照名称注入 (jdk)
4.生命周期
初始化:@PostConstruct
销毁: @PreDestroy
5.作用域 (类前)
@Scope("prototype") 多例
注意:
注解使用前提,导入aop的包,添加命名空间,让spring扫描含有注解类
spring-aop-4.3.5.RELEASE.jar
在配置文件中添加context标签:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> |
<!—扫描含有注解的包-->
<context:component-scan base-package="com.qf.annotation"></context:component-scan> |
6. 普通属性有关的注解
@value 注入属性值
1、加在成员变量上:通过反射的Field赋值(破坏对象的封装性)
@Value("慧慧") private String name; |
2、加在set方法上:通过set方法赋值
@Value("tom") public void setName(String name) { this.name = name; } |
@Value直接读取properties文件中的内容
a1 配置文件
<!-- 扫描properties文件 --> <context:property-placeholder location="classpath:dbinfo.properties"/> <!—扫描一次--> <!-- 扫描带有注解的包 指定要扫描的包 --> <context:component-scan base-package="com.itqf"></context:component-scan>
|
b1 在类中使用@value注解读取配置文件中的内容
@value(“${properties配置文件中的key}”)
@Value("${jdbc.driver}") private String driverClassName; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; |
11 Spring整合JUnit4测试
spring整合junit,为我们提供了方便的测试方式
1、导包:在spring-02-annotation项目中再加入如下包
spring-test-4.3.5.RELEASE.jar
junit4的包
2、创建测试类
//创建容器 @RunWith(SpringJUnit4ClassRunner.class) //指定创建容器时使用哪个配置文件 @ContextConfiguration("classpath:applicationContext.xml") public class RunWithTest { //将名为user的对象注入到u变量中 @Resource(name="person") private Person p; @Test public void testCreatePerson(){ System.out.println(p); } } |
IoC:控制反转 ,把对象的创建反转给spring来创建。
底层:静态工厂
DI:依赖注入,把类与类之间的依赖关系,交给spring注入。
功能:减少耦合度
创建对象三种方式:
bean中
inti-method
distory-method
bean的作用域
scope=”singleton” 默认 单例
prototype 多例
注入:
构造器注入
setter
p标签注入