Python 官方文档:入门教程 => 点击学习
目录1、jdk 动态代理和 CGLIB 代理有什么区别?2、FactoryBean、BeanFactory、ApplicationContext 有什么区别?3、说一说spring
getBean()
方法加载 Bean 对象,通常我们不会直接使用该接口,而是使用其子接口 ApplicationContext。getObject()
方法即可。Spring Bean 生命周期简单概括为 5 个阶段:
构造方法注入、Setter 方法注入、接口注入 三种。
依赖注入的相关注解
IOC 即控制反转,简单来说就是把原来代码里需要实现的对象创建、依赖反转给容器来帮忙实现,Spring 中管理对象及其依赖关系都是通过 Spring 的 IOC 容器实现的。
IOC 的实现方式有依赖注入和依赖查找,由于依赖查找使用的很少,因此 IOC 也叫做依赖注入。
我们之前在创建一个对象的时候都是直接 new
一个对象实例,而有了 IOC ,对象实例的创建都交给容器去实现即可。
我们以 XML 方式的容器初始化为例:
通过 ClassPathXmlApplicationContext
,去创建 ApplicationContext
容器对象:
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
ClassPathXmlApplicationContext
创建容器对象时,构造方法做了如下两件事:
loadBeanDefinitions()
方法加载 Bean 配置资源,该方法在加载资源时,首先解析配置文件路径,读取配置文件的内容,然后通过 XML 解析器将 Bean 的配置信息转换成文档对象,之后按照 Spring Bean 的定义规则将文档对象解析为 BeanDefinition 对象。先来看下面几行代码:
public class BeanFactoryTest {
public static void main(String[] args) {
// 加载与解析XML配置文件,获得BeanFactory:
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-bf.xml"));
// 从BeanFactory中加载Bean对象
Object a = beanFactory.getBean("componentA");
Object b = beanFactory.getBean("componentB");
System.out.println(a);// com.myspring.test.xmltest.ComponentA@1c93084c
System.out.println(b);// com.myspring.test.xmltest.ComponentB@6ef888f6
}
}
getBean()
方法,来获取 Bean 实例,该方法中,真正获取 Bean 实例的是其内层方法 doGetBean()
方法(真正实现从 IOC 容器获取 Bean ,也是触发依赖注入的地方)。doGetBean()
方法中,主要做了以下几件事:
transfORMedBeanName(name),
该方法的作用是,根据传入的 name 参数,获取真正的 Bean 对应的 beanName。该方法的 name 参数,有可能是一个别名(alias 属性设置的别名),也有可能是一个&开头的 name (工厂 Bean 对象)。transformedBeanName
方法转换 name 后得到的真实 beanName,getSingleton(beanName)
方法直接尝试从缓存中获取 Bean 的共享单实例,这时候获取的是初始状态,尚未实例化。(从缓存中加载的流程就是,根据 beanName 依次从一级缓存、二级缓存、三级缓存中尝试获取,通过三级缓存机制也可以有效避免循环依赖)getSingleton(beanName)
方法执行后,从缓存中得到了 Bean 的原始状态,接下来需要对该 Bean 进行实例化。doCreateBean()
方法创建 Bean。doGetBean
方法中的 requireType
参数不为空时,意味着我们对最后返回的 Bean 有着类型上的要求。Spring 通过 类型转换器 将第 ⑤ 步创建完成的 Bean 转换为 requireType
指定的类型。通过 scope 属性指定 Bean 的作用范围,包括:
singleton
:单例模式,是默认作用域,不管收到多少 Bean 请求每个容器中只有一个唯一的 Bean 实例。prototype
:原型模式,和 singleton 相反,每次 Bean 请求都会创建一个新的实例。request
:每次 Http 请求都会创建一个新的 Bean 并把它放到 request 域中,在请求完成后 Bean 会失效并被垃圾收集器回收。session
:和 request 类似,确保每个 session 中有一个 Bean 实例,session 过期后 bean 会随之失效。global session
:当应用部署在 Portlet 容器时,如果想让所有 Portlet 共用全局存储变量,那么该变量需要存储在 global session 中。Spring 的事务隔离级别底层其实是基于数据库的,Spring 并没有自己的一套隔离级别。
Spring 中的 AOP 目前支持 JDK 动态代理和 Cglib 代理。如果被代理对象实现了接口,则使用 JDK 动态代理,否则使用 Cglib 代理。另外,也可以通过指定 proxyTargetClass=true
来实现强制走 Cglib 代理。
应用场景:
@Aspect
:切面,声明被注解标注的类是一个切面 Bean。
@Aspect
@Component
public class LogAspect {
...
}
@Pointcut
:切入点,可以通过 @Pointcut("execution(* top.csp1999.service.impl.*.*(..))")
去指定要切入的目标对象,并对其符合表达式要求的方法进行增强。
@Pointcut("execution(* top.csp1999.service.impl.*.*(..))")
public void operationLog(){}
@Before
:前置通知,指在某个连接点之前执行的通知。
@Before("operationLog()")
public void doBeforeAdvice(JoinPoint joinPoint){
System.out.println("进入方法前执行.....");
}
@After
:后置通知,指某个连接点退出时执行的通知(不论正常返回还是异常退出)。
@After("operationLog()")
public void after(JoinPoint jp){
System.out.println("方法最后执行.....");
}
@AfterReturning
:后置返回通知,指某连接点正常完成之后执行的通知,返回值可以在返回后通知方法里接收。
@AfterReturning(returning = "ret", pointcut = "operationLog()")
public void doAfterReturning(Object ret) {
System.out.println("方法的返回值 : " + ret);
}
@AfterThrowing
:后置异常通知,指方法抛出异常导致退出时执行的通知,和@AfterReturning只会有一个执行,异常使用 throwing 属性接收。
@AfterThrowing(throwing = "jp", pointcut = "operationLog()")
public void throwss(JoinPoint jp){
System.out.println("方法异常时执行.....");
}
@Around
:环绕通知,可以用来在调用一个具体方法前和调用后来完成一些具体的任务。
@Around("operationLog()")
public Object run2(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取方法参数值数组
Object[] args = joinPoint.getArgs();
// 得到其方法签名
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// 获取方法参数类型数组
Class[] paramTypeArray = methodSignature.getParameterTypes();
if (EntityManager.class.isAssignableFrom(paramTypeArray[paramTypeArray.length - 1])) {
// 如果方法的参数列表最后一个参数是entityManager类型,则给其赋值
args[args.length - 1] = entityManager;
}
logger.info("请求参数为{}",args);
// 动态修改其参数
// 注意,如果调用joinPoint.proceed()方法,则修改的参数值不会生效,必须调用joinPoint.proceed(Object[] args)
Object result = joinPoint.proceed(args);
logger.info("响应结果为{}",result);
// 如果这里不返回result,则目标对象实际返回值会被置为null
return result;
}
Aspect
:切面,一个关注点的模块化,这个关注点可能会横切多个对象。
Joinpoint
:连接点,程序执行过程中的某一行为,即业务层中的所有方法。。
Advice
:通知,指切面对于某个连接点所产生的动作,包括前置通知、后置通知、返回后通知、异常通知和环绕通知。
Pointcut
:切入点,指被拦截的连接点,切入点一定是连接点,但连接点不一定是切入点。
Proxy
:代理,Spring AOP 中有 JDK 动态代理和 CGLib 代理,目标对象实现了接口时采用 JDK 动态代理,反之采用 CGLib 代理。
Target
:代理的目标对象,指一个或多个切面所通知的对象。
Weaving
:织入,指把增强应用到目标对象来创建代理对象的过程。
文章会不定时更新,有时候一天多更新几篇,还请三连支持一下,后续会亿点点的更新!也希望大家可以关注编程网其他文章!
--结束END--
本文标题: spring的13个经典面试题
本文链接: https://www.lsjlt.com/news/128241.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0