赞
踩
Spring 是分层的 full-stack(全栈) 轻量级开源框架,以 IoC 和 AOP 为内核,提供了展现层 Spring MVC 和业务层事务管理等众多的企业级应⽤技术,还能整合开源世界众多著名的第三⽅框架和类库,已
经成为使⽤最多的 Java EE 企业应⽤开源框架。
Spring是⼀个分层⾮常清晰并且依赖关系、职责定位⾮常明确的轻量级框架,主要包括⼏个⼤模块:
IoC Inversion of Control (控制反转/反转控制),注意它是⼀个技术思想,不是⼀个技术实现
描述的事情:Java开发领域对象的创建,管理的问题 传统开发⽅式:⽐如类A依赖于类B,往往会在类A中new⼀个B的对象IoC思想下开发⽅式:我们不⽤⾃⼰去new对象了,⽽是由IoC容器(Spring框架)去帮助我们实例化对
象并且管理它,我们需要使⽤哪个对象,去问IoC容器要即可
我们丧失了⼀个权利(创建、管理对象的权利),得到了⼀个福利(不⽤考虑对象的创建、管理等⼀系列 事情)
为什么叫做控制反转?
控制:指的是对象创建(实例化、管理)的权利
反转:控制权交给外部环境了(spring框架、IoC容器)
IoC解决对象之间的耦合问题
AOP: Aspect oriented Programming ⾯向切⾯编程/⾯向⽅⾯编程 AOP是OOP的延续
从OOP说起OOP三⼤特征:封装、继承和多态 oop是⼀种垂直继承体系
在不改变原有业务逻辑情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复
BeanFactory 和 ApplicationContext 都是 Spring Framework 中用于管理和获取 Bean
对象的核心接口,它们之间有一些重要的区别。
定义和作用:
BeanFactory 是 Spring 框架中最基础的接口,提供了 IoC (控制反转) 和 DI (依赖注入) 的核心功能。它负责实例化、配置和管理 Spring Bean。
它是 Spring IoC 容器的基础接口,定义了获取 Bean 的基本方法,如 getBean() 等。
延迟初始化:
BeanFactory 采用延迟初始化策略,即在第一次请求获取 Bean 时才会进行实例化和初始化。
功能简单:
功能相对较少,主要提供了 IoC 容器的基本功能,适用于对资源和性能有较高要求的环境。
典型实现类:
典型的 BeanFactory 实现类是 XmlBeanFactory,已在 Spring 5.x 中标记为过时,推荐使用 ApplicationContext 代替。
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
MyBean bean = (MyBean) beanFactory.getBean("myBean");
定义和作用:
ApplicationContext 是 BeanFactory 的子接口,它增加了更多的企业级功能。除了提供 BeanFactory 的所有功能外,还提供了更多的企业级特性,如国际化支持、事件发布机制、资源加载、AOP 支持等。
预加载和缓存:
ApplicationContext 在启动时会预加载所有的单例 Bean,并且提供了更好的性能和内存管理,因为它会缓存所有的 Bean 实例。
功能丰富:
除了 BeanFactory 的功能外,还提供了更多的企业级特性,使得 Spring 应用程序更加易于开发和管理。
典型实现类:
典型的 ApplicationContext 实现类有 ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext 等。
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
MyBean bean = (MyBean) context.getBean("myBean");
BeanFactory 采用延迟初始化,只在需要时才实例化 Bean。
ApplicationContext 在启动时会预加载所有的单例 Bean,并且可以提供更好的性能和内存管理。
BeanFactory 提供了基本的 IoC 容器功能。
ApplicationContext 在 BeanFactory 的基础上增加了更多的企业级特性,如事件发布、AOP 支持、国际化支持等。
@Autowired(推荐使⽤) @Autowired为Spring提供的注解,需要导⼊包 org.springframework.beans.factory.annotation.Autowired。 @Autowired采取的策略为按照类型注⼊。
public class TransferServiceImpl { @Autowired private AccountDao accountDao;
}
如上代码所示,这样装配回去spring容器中找到类型为AccountDao的类,然后将其注⼊进来。这 样会产⽣⼀个问题,当⼀个类型有多个bean值的时候,会造成⽆法选择具体注⼊哪⼀个的情况, 这个时候我们需要配合着@Qualifier使⽤。
@Qualifier告诉Spring具体去装配哪个对象。
@Resource @Resource 注解由 J2EE 提供,需要导⼊包 javax.annotation.Resource。
@Resource 默认按照 ByName ⾃动注⼊。
@Resource 在 Jdk 11中已经移除,如果要使⽤,需要单独引⼊jar包
@Configuration 注解,表名当前类是⼀个配置类
@ComponentScan 注解,替代 context:component-scan
@PropertySource,引⼊外部属性配置⽂件 @Import 引⼊其他配置类 @Value 对变量赋值,可以直接赋值,也可以使⽤ ${} 读取资源配置⽂件中的信息
@Bean 将⽅法返回对象加⼊ SpringIOC 容器
Bean的延迟加载(延迟创建)
ApplicationContext 容器的默认⾏为是在启动服务器时将所有 singleton bean 提前进⾏实例化。提前 实例化意味着作为初始化过程的⼀部分,ApplicationContext 实例会创建并配置所有的singletonbean。
BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚, 具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext;此处我们重点分析FactoryBean
Spring中Bean有两种,⼀种是普通Bean,⼀种是⼯⼚Bean(FactoryBean),FactoryBean可以⽣成 某⼀个类型的Bean实例(返回给我们),也就是说我们可以借助于它⾃定义Bean的创建过程。
Bean创建的三种⽅式中的静态⽅法和实例化⽅法和FactoryBean作⽤类似,FactoryBean使⽤较多,尤其在Spring框架⼀些组件中会使⽤,还有其他框架和Spring框架整合时使⽤
FactoryBean 是一个接口,用于在 Spring 容器中定义和配置复杂的 Bean 实例化逻辑。它允许自定义 Bean 的实例化过程,而不受限于标准的构造函数或静态工厂方法。
实现 FactoryBean 接口的类必须实现 getObject() 方法,该方法返回一个由该工厂创建的实际 Bean 实例。
自定义 Bean 实例化过程:
FactoryBean 提供了更高级别的控制和定制化,允许程序员在创建 Bean 实例时执行自定义逻辑。
实现步骤:
创建一个实现 FactoryBean 接口的类,并实现 getObject() 方法,定义如何创建 Bean 实例。
在 Spring 配置文件中声明该 FactoryBean 的 Bean 定义。
Spring提供了两种后处理bean的扩展接⼝,分别为 BeanPostProcessor 和 BeanFactoryPostProcessor,两者在使⽤上是有所区别的。
在Bean对象实例化(并不是Bean的整个⽣命周期完成)之后可以使⽤BeanPostProcessor进⾏后置处理做⼀些事情
定义⼀个类实现了BeanPostProcessor,默认是会对整个Spring容器中所有的bean进⾏处理。如果要对
具体的某个bean处理,可以通过⽅法参数判断,两个类型参数分别为Object和String,第⼀个参数是每
个bean的实例,第⼆个参数是每个bean的name或者id属性的值。所以我们可以通过第⼆个参数,来判断我们将要处理的具体的bean。
package com.xxx; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; /** * @Author 应癫 * @create 2019/12/3 16:59 */ public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor() { System.out.println("BeanPostProcessor 实现类构造函数..."); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if("xxx".equals(beanName)) { System.out.println("BeanPostProcessor 实现类 postProcessBeforeInitialization ⽅法被调⽤中......"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if("xxx".equals(beanName)) { System.out.println("BeanPostProcessor 实现类 postProcessAfterInitialization ⽅法被调⽤中......"); } return bean; } }
在BeanFactory初始化之后可以使⽤BeanFactoryPostProcessor进⾏后置处理做⼀些事情
BeanDefinition对象:我们在 XML 中定义的 bean标签,Spring 解析 bean 标签成为⼀个 JavaBean,
这个JavaBean 就是 BeanDefinition 注意:调⽤ BeanFactoryPostProcessor
⽅法时,这时候bean还没有实例化,此时 bean 刚被解析成BeanDefinition对象
package com.xxx;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor; importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/** * @Author 应癫
* @create 2019/12/3 16:56 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() { System.out.println("BeanFactoryPostProcessor的实现类构造函数...");
}
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryPostProcessor的实现⽅法调⽤中......");
}
}
循环依赖其实就是循环引⽤,也就是两个或者两个以上的 Bean 互相持有对⽅,最终形成闭环。⽐如A 依赖于B,B依赖于C,C⼜依赖于A。
Spring中循环依赖场景有:
Spring 的循环依赖的理论依据基于 Java 的引⽤传递,当获得对象的引⽤时,对象的属性是可以延后设置的,但是构造器必须是在获取引⽤之前
Spring通过setXxx或者@Autowired⽅法解决循环依赖其实是通过提前暴露⼀个ObjectFactory对 象来完成的,简单来说ClassA在调⽤构造器完成对象初始化之后,在调⽤ClassA的setClassB⽅法之前就把ClassA实例化的对象通过ObjectFactory提前暴露到Spring容器中。
spring 实现AOP思想使⽤的是动态代理技术 默认情况下,Spring会根据被代理对象是否实现接⼝来选择使⽤JDK还是CGLIB。当被代理对象没有实现 任何接⼝时,Spring会选择CGLIB。当被代理对象实现了接⼝,Spring会选择JDK官⽅的代理技术,不过
我们可以通过配置的⽅式,让Spring强制使⽤CGLIB。
连接点:⽅法开始时、结束时、正常运⾏完毕时、⽅法异常时等这些特殊的时机点,我们称之为连接 点,项⽬中每个⽅法都有连接点,连接点是⼀种候选点
切⼊点:指定AOP思想想要影响的具体⽅法是哪些,描述感兴趣的⽅法 Advice增强:
第⼀个层次:指的是横切逻辑
第⼆个层次:⽅位点(在某⼀些连接点上加⼊横切逻辑,那么这些连接点就叫做⽅位点,描述的是具体 的特殊时机)
Aspect切⾯:切⾯概念是对上述概念的⼀个综合 Aspect切⾯= 切⼊点(@pointcut)+增强
= 切⼊点(锁定⽅法) + ⽅位点(锁定⽅法中的特殊时机)+ 横切逻辑
从操作的⻆度来描述,事务中的各个操作要么都成功要么都失败
⼀致性(Consistency)
事务必须使数据库从⼀个⼀致性状态变换到另外⼀个⼀致性状态。 例如转账前A有1000,B有1000。转账后A+B也得是2000。 ⼀致性是从数据的⻆度来说的,(1000,1000) (900,1100),不应该出现(900,1000)
隔离性(Isolation)
事务的隔离性是多个⽤户并发访问数据库时,数据库为每⼀个⽤户开启的事务, 每个事务不能被其他事务的操作数据所⼲扰,多个并发事务之间要相互隔离。
⽐如:事务1给员⼯涨⼯资2000,但是事务1尚未被提交,员⼯发起事务2查询⼯资,发现⼯资涨了2000 块钱,读到了事务1尚未提交的数据(脏读)
持久性(Durability)
持久性是指⼀个事务⼀旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发⽣故障也不应该对其有任何影响。
@EnableTransactionManagement
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。