Spring基础
2021-03-21 15:26
标签:调用顺序 顺序 row stp before 应用 factory 业务逻辑 order 什么是Spring? Spring框架存在的意义就是为了降低耦合度, 根据不同的代码采用不同的方式, 通过IOC来降低主业务逻辑之间的耦合度, 通过AOP来降低系统级服务(如日志、安全、事务等)和主业务逻辑之间的耦合度. 此外还提供了一个Web层的框架Spring MVC. 在介绍Spring容器之前, 我们先介绍什么是bean. 简单来说, 被Spring容器管理的对象就叫bean, 比如Controller/Action, Service, Dao. Spring容器管理着项目中所有bean对象的实例化与装配, 有两种, 分别是 BeanFactory 和 ApplicationContext. 其中 ApplicationContext 是 BeanFactory 的一个子接口, 补充了以下几个功能: 上述几个功能只需了解就行, 对于两者的区别, 我们需要记住的是: 大部分情况下我们使用的都是ApplicationContext, 这篇博客下面的内容也都是基于ApplicationContext. 配置元数据 Spring容器通过读取元数据来获取要实例化、装配的对象. 元数据有三种格式, 分别是XML文件, Java注解和Java代码. 上面这段代码就是基于XML文件的元数据, ApplicationContext 的两个实现类 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext 用来加载XML格式的元数据. 两者的区别在于 ClassPathXmlApplicationContext 是基于类路径, 而 FileSystemXmlApplicationContext 是基于文件路径. ApplicationContext的实现类AnnotationConfigApplicationContext用来加载Java注解格式的元数据. IoC也称为依赖注入(dependency injection, DI). 这是一个过程, 在这个过程中, 首先通过在对象实例上设置的属性来定义bean之间的依赖关系, 然后Spring容器在创建bean时注入这些依赖项(这个注入过程也叫做装配). 依赖注入有两种, 分别是基于构造方法的注入和基于Setter方法的注入. 基于构造方法注入 基于Setter方法的注入 Bean的作用域有六种, 其中后四种只支持Web应用. singleton和application的区别 (1) 在作用域为singleton时, bean在每一个Spring容器内只有一个实例, 而应用可以有多个容器. 具有多例bean依赖的单例bean 一个bean的作用域是 singleton, 而它的属性的作用域是 prototype, 如下所示: 我们想要的效果是, 每次获取BookServiceId时都是同一个bean, 而它的属性BookDaoId都是一个新的bean. 但这种情况是不可能的, 因为BookServiceId只会实例化, 装载一次. 要想达到我们期望的效果, 需要使用方法注入: 方法注入 Spring框架通过使用来自CGLIB库的字节码生成器来动态生成覆盖该方法的子类来实现此方法注入. 生命周期回调 (1) 初始化回调 在Spring容器将bean实例化, 设置属性值之后将会执行初始化回调. 初始化回调有两种设置方式: (2) 销毁回调 当bean被销毁之前, 将会执行销毁回调. 销毁回调有两种设置方式: (3) 初始化回调 / 销毁回调的两种方式同时配置 当 初始化回调 / 销毁回调的两种方式同时配置时会出现什么结果呢? 结果是两种方式都执行, 但 DisposableBean / InitializingBean 在前, destroy-method / init-method 在后. (4) 启动和关闭回调 如果Spring容器中的bean实现了 Lifecycle 接口, 当Spring容器启动时, 将会调用这些bean的start()方法, 当Spring容器关闭时, 将会调用这些bean的stop()方法. 在很多情况下, start()方法和stop()方法的调用顺序是重要的, 如果两个bean存在依赖关系, 比如 a 依赖 b (b是a的属性), 这时 a 先调用start()方法, b 先调用stop()方法. 但如果我们不知道依赖关系, 却想让 a 在 b 之前调用start()方法, 这时我们就可以用 SmartLifecycle 接口代替 Lifecycle 接口. SmartLifecycle接口的方法介绍: 当 isAutoStartup() 返回true, Spring容器启动时会调用bean的 start() 方法 当 isRunning() 返回true, Spring容器销毁时会调用bean的 stop(Runnable runnable) 方法 getPhase() 返回的是优先级, 当有多个bean时, 返回值大的先执行start()方法, 销毁时顺序相反. 容器内没有实现SmartLifecycle接口, 而实现了Lifecycle接口的bean返回值是0. 负数代表最高优先级. BeanPostProcessor 如果我们想在Spring容器完成bean的初始化前后加一些定制逻辑, 我们可以向容器注册一个或多个定制BeanPostProcessor实现. 当有多个BeanPostProcessor定制时, 我们同时要实现Ordered接口. bean的生命周期 bean在Spring容器中的生命周期是怎么样的呢? FactoryBean 面试中常常问到FactoryBean和BeanFactory的区别, 我们已经知道BeanFactory是一个Spring容器, 应用中所有bean的实例都存储在其中, 那FactoryBean是什么呢? FactoryBean是一个生成bean的工厂. 一般情况下我们都是用XML文件来配置bean, 但如果我们有复杂的初始化逻辑, 相对于冗长的XML, 用Java代码可以更好地表达, 这时我们就可以创建自己的FactoryBean, 在该类中编写复杂的初始化逻辑, 然后将定制的FactoryBean插入容器中. Spring基础 标签:调用顺序 顺序 row stp before 应用 factory 业务逻辑 order 原文地址:https://www.cnblogs.com/xiaoxin-IT/p/13885096.htmlSpring容器
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/bean.xml");
ApplicationContext context = new FileSystemXmlApplicationContext("D:\\springtest\\src\\main\\resources\\spring\\bean.xml");
@Configuration
@ComponentScan(basePackages = "org.tyshawn")
public class AppConfig {
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
IOC
public interface IBookDao {
void insert();
}
public class BookDaoImpl implements IBookDao {
@Override
public void insert() {
System.out.println("add book");
}
}
public interface IBookService {
void addBook();
}
public class BookServiceImpl implements IBookService {
private IBookDao bookDao;
public BookServiceImpl(IBookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void addBook() {
this.bookDao.insert();
}
}
public interface IBookDao {
void insert();
}
public class BookDaoImpl implements IBookDao {
@Override
public void insert() {
System.out.println("add book");
}
}
public interface IBookService {
void addBook();
}
public class BookServiceImpl implements IBookService {
private IBookDao bookDao;
public void setBookDao(IBookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void addBook() {
this.bookDao.insert();
}
}
Bean的作用域
作用域
描述
singleton
默认. bean在每一个Spring容器内只有一个实例
prototype
每次从Spring容器中获取到的bean都是一个新的实例
request
bean在每一个 HTTP Request 中只有一个实例, 只支持Web应用
session
bean在每一个 HTTP Session 中只有一个实例, 只支持Web应用
application
bean在每一个 ServletContext 中只有一个实例, 只支持Web应用
websocket
bean在每一个 WebSocket 中只有一个实例, 只支持Web应用
(2) 在作用域为application时, bean在整个应用中只有一个实例.
(3) 作用域application只支持Web应用.public class BookServiceImpl implements IBookService {
private IBookDao bookDao;
public IBookDao getBookDao() {
return bookDao;
}
@Override
public void addBook() {
IBookDao bookDao = getBookDao();
System.out.println(bookDao);
}
}
Bean的生命周期
方式一(推荐)
方式一(推荐)
public interface Lifecycle {
void start();
void stop();
boolean isRunning();
}
public interface Phased {
int getPhase();
}
public interface SmartLifecycle extends Lifecycle, Phased {
boolean isAutoStartup();
void stop(Runnable callback);
}
(1) 实例化
(2) 设置属性值
(3) 调用BeanNameAware的setBeanName()方法
(4) 调用BeanFactoryAware的setBeanFactory()方法
(5) 调用ApplicationContext的setApplicationContext()方法
(6) 调用BeanPostProcessor的postProcessBeforeInitialization()方法
(7) 调用InitializingBean的afterPropertiesSet()方法
(8) 调用xml配置的初始化方法
(9) 调用BeanPostProcessor的postProcessAfterInitialization()方法
(10) 容器启动.
(11) bean可以使用了.
(12) 容器关闭.
(13) 调用DisposableBean的destory()方法
(14) 调用xml配置的销毁方法
上一篇:Spark_Spring