Spring学习笔记整理
优点
- 非侵入式设计
- 方便解耦,简化开发
- 支持AOP
- 支持声明式事务处理
- 方便程序测试
- 方便集合各种优秀框架
- 降低JavaEE API使用难度
spring组成
- spring核心容器 Core Container
- Beans 提供BeanFactory Spring框架的主要功能是通过其核心容器来实现的。Spring框架提供了两种核心容器,分贝为BeanFactory和ApplicationContex。
- Core Spring框架基本组成部分,IOC和DI功能
- Context 建立在Beans和Core基础上,访问定义和配置的任何对象的媒介
- SpEL Spring3.0新增的模块,运行查询和操作对象图的强大表达式语言
- Data Access/Integration数据访问和集成
- JDBC 减少开发过程中对数据库操作的编码
- ORM 对象关系映射API 包括JPA JDO和Hibernate的继承支持
- OXM 对/xml映射的抽象层实现,例如JAXB CASTOR XMLBEANS JIBX XSTREAM
- JMS Java消息服务
- Transaction 对事务管理接口
- Web
- WebSocket
- Servlet 也称spring webmvc模块,spring模型-视图-控制器 和Rest Web Service
- Web web开发特性,文件上传,Servlet监听器初始化IOC
- Portlet 在portlet环境实现Servlet
- 其他
- AOP
- Aspect
- Instrumentation
- Messaging
bean作用域 scope spring4.3 七种作用域
- singleton 单例 spring容器默认的作用域,当bean的作用域为singleton时,Spring容器就只会存在一个共享的bean实例,singleton作用域对于无会话状态的Bean是最理想的选择
- prototype 原型 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时 ,相当于执行new Bean() 对于需要保持会话状态的Bean应该使用prototype的作用域,在使用prototype作用域时,spring容器会为每一个请求创建一个新的实例
- request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
- session 同一个HTTP Session 共享一个Bean,不同Session使用不同Bean,仅适用于WebApplicationContext 环境
- globalSession 一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext 环境
- application 为每个servletContext对象创建一个实例,仅在web相关的applicationContext中生效
- websocket 为每个websocket对象创建一个实例,仅在web相关的applicationContext中生效
bean 生命周期
- Bean实例化和依赖注入
- bean对象实例化
- 封装属性(属性注入)
- beanName
- 如果Bean实现BeanNameAware 执行setBeanName
- 如果Bean实现BeanFactoryAware 执行setBeanFactory ,获取Spring容器
- 如果Bean实现ApplicationContextAware 调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。
- 前置处理器
- 如果Bean实现BeanPostProcessor 执行postProcessBeforeInitialization() 预初始化方法、实例化、依赖注入完毕,在调用初始化之前完成一些定制的初始化任务
- 初始化方法
- 如果Bean实现InitializingBean 执行afterPropertiesSet()
- 调用 指定自定义初始化方法
- 后置处理器
- 如果Bean实现BeanPostProcessor 执行postProcessAfterInitialization 初始化后方法,初始化完毕时执行
- 业务处理
- Bean已经准备就绪,可以执行业务处理
- 销毁方法
- 如果Bean实现DisposableBean接口 Spring将调用它的destory()接口方法
- 调用 指定自定义销毁方法
package com.gyf.model;
/**
* bean的生命周期
*/
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanLifeCycle implements
BeanNameAware, BeanFactoryAware, ApplicationContextAware,
InitializingBean, DisposableBean, BeanPostProcessor {
private String name;
private String password;
public BeanLifeCycle(){
System.out.println("1.实例化");
}
public BeanLifeCycle(String name, String password){
System.out.println("1.实例化 ");
this.name = name;
this.password = password;
System.out.println("2. 构造方法注入依赖属性");
}
public void setName(String name) {
System.out.println("2.setter方法注入属性" + name);
this.name = name;
}
public void setPassword(String password) {
System.out.println("2.setter方法注入属性" + password);
this.password = password;
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
@Override
public void setBeanName(String s) {
//设置bean的名字
System.out.println("3.设置bean的名字" + s);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
//把对象放进容器里,工厂里
System.out.println("4.获取bean工厂 "+ beanFactory);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("5. Spring将bean所在应用上下文引用传入进来: " + applicationContext);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("6.前置处理器 实例化和依赖注入后,在初始化方法的前" + bean + " beanName: " + beanName);
return null;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("7.初始化方法");
}
public void myInit(){
System.out.println("8.自定义赋值方法");
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("9.后置处理器 实例化和依赖注入后,在初始化方法的后");
return null;
}
public void sayHello(){
System.out.println("10. 执行业务");
}
@Override
public void destroy() throws Exception {
System.out.println("11.销毁方法 ");
}
public void myDestory(){
System.out.println("12.自定义的销毁方法");
}
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beanLifeCycle.xml");
BeanLifeCycle beanLifeCycle = (BeanLifeCycle) context.getBean("beanLifeCycle3");
beanLifeCycle.sayHello();
context.close();
}
}
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="beanLifeCycle" class="com.gyf.model.BeanLifeCycle" init-method="myInit" destroy-method="destroy">
<constructor-arg index="0" value="name"></constructor-arg>
<constructor-arg index="1" value="passowrd"></constructor-arg>
</bean>
<bean name="beanLifeCycle2" class="com.gyf.model.BeanLifeCycle" init-method="myInit" destroy-method="destroy">
<property name="name" value="setter方法注入name"></property>
<property name="password" value="setter方法注入password"></property>
</bean>
<bean name="beanLifeCycle3" class="com.gyf.model.BeanLifeCycle" init-method="myInit" destroy-method="destroy"
p:name="命名空间注入name" p:password="命名空间注入password">
</bean>
</beans>
spring 容器加载方式
- 类路径classpath中寻找指定的xml配置文件
类加载器加载 beans.xml ClassPathXmlApplicationContext类路径加载【主要】
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
userService = (UserService) context.getBean("service1");
- 在指定的文件系统路径中寻找xml配置文件 【绝对路径】
String path = "F:\\Java_home\\SpringDemo\\src\\main\\resources\\beans.xml";
ApplicationContext context2 = new FileSystemXmlApplicationContext(path);
userService = (UserService) context2.getBean("service1");
- 第三种方式:使用 BeanFactory()
String path = "F:\\Java_home\\SpringDemo\\src\\main\\resources\\beans.xml";
BeanFactory factory = new XmlBeanFactory(new FileSystemResource(path));
UserServiceImpl user = (UserServiceImpl)factory.getBean("service2");
实例化bean的三种方式: 实例化bean
Bean实例化 bean对象实例化 xml、properties 配置
<?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">
<!-- 构造方法实例化 -->
<bean id="bean1" class=" cc.xml.Bean" ></bean>
<!-- 静态工厂 -->
<bean id="beanStaticFactory" class="cc.xml.BeanStaticFactory"
factory-method="createBean"></bean>
<!-- 实例工厂 -->
<bean id="myFactory" class="cc.xml.BeanInstanceFactory"/>
<bean id="beanInstanceFactory" factory-bean="myFactory" factory-method="createBean"></bean>
</beans>
- 构造器实例化 常用
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Bean{
private String message;
public Bean() {
System.out.println("构造方法实例化");
}
public Bean(String me) {
this.message = me;
}
public void say() {
System.out.println("\n"+ message + "创建的 Bean1 ");
}
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
//构造方法
Bean usr = (Bean) context.getBean("bean1");
usr.say();
}
}
- 通过静态工厂方法
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 静态工厂
* @author newChenyingtao
*
*/
public class BeanStaticFactory {
private static Bean bean;
public static Bean createBean() {
System.out.println("调用静态工厂");
return new Bean("静态工厂");
}
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
//静态工厂
Bean b1 = (Bean) context.getBean("beanStaticFactory");
b1.say();
}
}
- 通过实例工厂方法
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 实例工厂
* @author newChenyingtao
*
*/
public class BeanInstanceFactory {
public Bean createBean() {
System.out.println("调用实例工厂");
return new Bean("实例工厂");
}
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
//实例工厂
Bean b2 = (Bean) context.getBean("beanInstanceFactory");
b2.say();
}
}
Spring装配:自动化装配,Java配置装配,XML配置装配 依赖注入bean的属性 Spring 实现 Dependency Injection
springXML配置装配: 手动注入三种方式(构造方法,setter方法,命名空间)
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
1. 使用构造方法注入属性值 需要:有参数的构造方法
<bean name="beanLifeCycle" class="com.gyf.model.BeanLifeCycle"
init-method="myInit" destroy-method="destroy">
<constructor-arg index="0" value="name"></constructor-arg>
<constructor-arg index="1" value="passowrd"></constructor-arg>
</bean>
2. 通过setter方法注入属性值 需要:无参的构造方法和setter方法
<bean name="beanLifeCycle2" class="com.gyf.model.BeanLifeCycle"
init-method="myInit" destroy-method="destroy">
<property name="name" value="setter方法注入name"></property>
<property name="password" value="setter方法注入password"></property>
</bean>
3. 命名空间注入属性 这个需要有空参的构造方法 setter方法
<bean name="beanLifeCycle3" class="com.gyf.model.BeanLifeCycle"
init-method="myInit" destroy-method="destroy"
p:name="命名空间注入name" p:password="命名空间注入password">
</bean>
</beans>
spring 注解装配 Java配置装配 基于Annotation
- @component取代 @Component(id="") 取代
web开发3个@Component注解衍生注解
- @Repository(“名称”): dao层
- @Service(“名称”): service层
- @Controller(“名称”): web层
- @Autowired:自动根据类型注入 :如果是一个接口就找接口的实现类, 如果时一个类查找类
- @Qualifier(“名称”):指定自动注入的id名称
- @Resource(“名称”) 等于
- @Scope(“prototype”) 生命周期注释
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class BeanClass {
public void sayHello() {
System.out.println("hello world");
}
public static void main(String[] args) {
ClassPathXmlApplicationContext con = new ClassPathXmlApplicationContext("annotation.xml");
BeanClass c = con.getBean(BeanClass.class);
c.sayHello();
}
}
自动化装配 隐式的Bean发现机制和自动装配
Spring从两个角度来实现自动化装配;
组件扫描(Spring 自动发现应用中上下文所需要的创建的Bean)
自动装配(Spring 自动满足Bean之间的依赖)
- 使用@Component 将普通Java类配置成SpringBean
- 使用@Autowired(自动装配)使Spring满足Bean的依赖
- 配置组件扫描包(组件扫描)
在Java类中配置组件扫描 @ComponentScan(“com.gyf.model”)
在XML配置文件配置组件扫描 <context:component-scan base-package=“com.gyf.model”/>