Spring 概念
1.非持久层框架
持久层:Mybatis|Hibernate
可以用于集成持久层框架
2.非试图层框架
试图层:SpringMvc(主流) |Struts2|Struts1(弃用)
可以用于集成试图层框架
3.基本概念
分层框架一站式(一条龙):基本可以满足web项目开发需要,轻量级(配置简单,-零配置开发(注解))
两大核心内容
IOC(控制反转与依赖注入) .AOP(面向切面编程)–oop面向对象
解耦:高内聚 低耦合 Bean实例化 注入(依赖)
Spring相关服务(功能):邮件服务(邮件的发送).事物控制(AOP),定时任务的执行(Quartz),JMS
Spring 框架模块划分
1.Spring - IOC:控制反转与依赖注入
2.Spring - AOP:面向切面编程
3.Spring - JDBC:持久层操作
4.Spring - mvc: Web Servlet
5.Spring - Test:单元测试
Spring框架环境的搭建
最终目标–>使用Spring框架实现对象的实例化,借助控制台实现对象方法的调用该
1.创建Spring普通工程
使用Idea创建Maven普通工程 quick-start
2.添加核心坐标
<!-- Spring 核心坐标 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
3.添加Bean对象代码
package com.shsxt.service;
public class UserService {
public void test(){
System.out.println("hello Spring");
}
}
4.配置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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!---
配置需要交给spring 框架实例化的对象
id:Bean对象唯一标识
class:Bean 对象全路径
-->
<bean id="userService" class="com.shsxt.service.UserService"></bean>
</beans>
5.执行测试
package com.shsxt;
import com.shsxt.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Starter {
public static void main(String[] args) {
//原始用法
/* UserService userService=new UserService();
userService.test();*/
ApplicationContext ac =new ClassPathXmlApplicationContext("beans.xml");
UserService userService= (UserService) ac.getBean("userService");
userService.test();
UserService userService1= (UserService) ac.getBean("userService");// 单例对象
System.out.println(userService+","+userService1);
}
}
Spring IOC容器的实现思路分析
ApplicationContext ac =new ClassPathXmlApplicationContext("beans.xml");
UserService userService= (UserService) ac.getBean("userService");
思路分析:
技术点
工厂设计模式
xml解析-dom4j
反射
单例
实现方案
1.定义工厂类 -接口-SxtBeanFactory
Object getBean(String beanName);
2.定义实现类 实现SxtBeanFactory
/**
-
思路:
-
1.文件加载
-
将xml文件加载到内存
-
2.xml 解析
-
dom4j
-
读取bean 标签 获取 id class
-
内容如何存取-集合List<Map|JavaBean> Map<id,Class>
-
3.对象的实例化
-
遍历集合 List|Map
-
id-class :反射实例化对象 -->Map<id,Object>
-
4.返回对象
-
map.get(id)
Spring IOC核心设计模式
1.单例-懒汉 饿汉 枚举 防止反射
2.工厂设计模式(抽象工厂)
3.xml解析技术
4.反射技术
5.自定义注解
6.策略模式
Spring IOC依赖注入(DI)-手动装配
1.set注入
Spring IOC内部通过set方法实现Bean对象注入
1.添加属性Set方法
public class RoleService {
private UserService userService;
private AccountService at;
private String roleName;
private Integer age;
private String host;
private Integer port;
public void setPort(Integer port) {
this.port = port;
}
public void setHost(String host) {
this.host = host;
}
public void setAge(Integer age) {
this.age = age;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public void setAt(AccountService at) {
this.at = at;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public void test01(){
System.out.println("roleService.test01..."+roleName+","+age+","+host+","+port);
userService.test();
at.test();
}
}
2.加入Bean标签的子标签 property
<!---
对象的依赖注入
name:属性名称值
ref:当前属性名对应的Bean 对象 目标对象的唯一标识
-->
<bean id="roleService" class="com.shsxt.service.RoleService">
<property name="userService" ref="userService"></property>
<property name="at" ref="accountService"></property>
<property name="roleName" value="admin"></property>
<property name="age" value="20"></property>
<property name="host" value="192.168.10.20"></property>
<property name="port" value="25"></property>
</bean>
<bean id="userService" class="com.shsxt.service.UserService"></bean>
<bean id="accountService" class="com.shsxt.service.AccountService"></bean>
2.构造器注入(带参)
1.提供带参构造方法
2.添加bean标签子标签 constructor-arg标签 name ref(同set注入)
<bean id="userService" class="com.shsxt.service.UserService">
<constructor-arg name="accountService" ref="accountService"></constructor-arg>
<constructor-arg name="host" value="192.168.10.20" ></constructor-arg>
</bean>
3.需要注意的是可能会出现循环引用,解决方案是使用set注入
3.静态工厂(依赖set)
<!---
对象的依赖注入-静态工厂
name:属性名称值
ref:当前属性名对应的Bean 对象 目标对象的唯一标识
-->
<bean id="userService" class="com.shsxt.service.UserService">
<property name="resourceService" ref="resourceService"></property>
</bean>
<bean id="resourceService" class="com.shsxt.factory.StaticFactory" factory-method="getResourceService"></bean>
4.实例化工厂(依赖set)
<!---
对象的依赖注入-实例化工厂
name:属性名称值
ref:当前属性名对应的Bean 对象 目标对象的唯一标识
-->
<bean id="userService" class="com.shsxt.service.UserService">
<property name="goodsService" ref="goodsService"></property>
</bean>
<bean id="instanceFactory" class="com.shsxt.factory.InstanceFactory"></bean>
<bean id="goodsService" factory-bean="instanceFactory" factory-method="getGoodsService"></bean>
Spring IOC Bean自动化装配
环境配置
引入context命名空间和xsd地址
添加context:annotation-config/ 配置
<?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"
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:annotation-config/>
</beans>
@Resource:声明在属性字段或者set方法上,使用频率高,不依赖框架包
默认按照属性名实现注入 如果属性名未找到对应bean 按照类型(class实现注入)
如果存在接口多个实现,声明resource的name属性指定具体的实现类@Resource(name=“值”)
@Resource
private ResourceService resourceService;
@Resource(name = "xxServiceImpl01")
private IXxService xxService;
@Autowired:多用于声明在属性字段或者set方法上,属于框架内部注解,依赖于框架
默认按照class类型实现bean的注入,可以按照名称实现Bean的注入,此时需要配合@Qualifier注解
@Autowired
@Qualifier("accountService")
private AccountService as;
Spring IOC 集合类型属性注入
list 集合注入
<bean id="userServiceImpl" class="com.shsxt.service.impl.UserServiceImpl">
<property name="list">
<list>
<value>河南烩面</value>
<value>南方臊子面</value>
<value>油泼面</value>
<value>方便面</value>
</list>
</property
</bean>
遍历list
clties.forEach(c->{
system.out.printLn(c)
})
map 类型属性注入
<bean id="userServiceImpl" class="com.shsxt.service.impl.UserServiceImpl">
<property name="map">
<map>
<entry>
<key><value>河南</value></key>
<value>云台山风景</value>
</entry>
<entry>
<key><value>上海</value></key>
<value>宝塔</value>
</entry>
<entry>
<key><value>北京</value></key>
<value>紫禁城</value>
</entry>
</map>
</property>
</bean>
遍历Map
map.forEach((k,v)->{
system.out.println(k+","+v)
}
配置扫描器,指定扫描包范围
Dao层:@Repository
Service层:@Service
控制层:@Controller
不确定层:@Component
被实例化的Bean, 如果没有特别声明名称的,就默认为Bean的id为类名首字母小写
加入以下约束
<?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"
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.shsxt"/>
</beans>
作用域:scope
1.singleton(默认)
lazy-init:默认是flase,即IOC启动时实例化bean
true:不会对bean实例化
优点:
1.及时的发现应用程式中的潜在问题
2.通过程序的运行效率
什么样的对象适合被Spring框架管理
线程安全?火车票出票
Spring IOC管理的Bean为无状态Bean
有状态的Bean是含有成员属性的
<bean id="userServiceImpl" class="com.shsxt.service.impl.UserServiceImpl" lazy-init="flase" ></bean>
2.protype
3.web作用域:request作用域 session作用域
Bean的生命周期
Bean 的生命周期包括: Bean 的定义、初始化、使用和销毁 4 个阶段
Spring bean 初始化有两种方式:
I.在配置文档中通过指定 init-method 属性来完成。
<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl"
init-method="init" >
Bean 的销毁
实现销毁方式(spring 容器会维护 bean 对象的管理,可以指定 bean 对象的销毁所要执行的方法)
<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl" init-method="init" destroy-method="destroy">
</bean>
通过 AbstractApplicationContext 对象,调用其 close 方法实现 bean 的销毁过程。
AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("spring-application.xml");
ctx.close();