当前位置: 首页 > news >正文

一、Spring

一、Spring

0. Spring事务?

二、Spring事务

1. Spring如何解决循环依赖的问题?

详情参考:https://blog.csdn.net/qq_36381855/article/details/79752689
(即A依赖B,B依赖C、C依赖A)
循环依赖种类:
①构造器的循环依赖。【这个Spring解决不了】:A的构造方法中依赖了B的实例对象,同时B的构造方法中依赖了A的实例对象;
②【setter循环依赖】field属性的循环依赖:A的某个field或者setter依赖了B的实例对象,同时B的某个field或者setter依赖了A的实例对象;
为啥Spring不能解决“A的构造方法中依赖了B的实例对象,同时B的构造方法中依赖了A的实例对象(即构造器的循环依赖)”这类问题了!因为加入singletonFactories三级缓存的前提是执行了构造器,所以构造器的循环依赖没法解决。

两种方式:?
第一步:将构造函数注入方式改为 属性注入方式 ;(因为Spring解决不了)
第二步:使用延迟加载(使用到的时候再创建);(三级缓存?参考:http://zengbingo.com/p/1985.html)

1. Spring中用到的设计模式有哪些?

Spring 中经典的 9 种设计模式:

单例模式、工厂模式?(简单工厂、工厂方法)、代理模式、适配器模式、包装器模式(装饰器模式)、观察者模式、模板方法模式、策略模式等;
①单例模式:scope值为 singleton、或者不写时默认单例 ;scope值改为 prototype表示多例(singleton=“true|false” 或者 scope=“singleton|prototype”来指定);
②简单工厂:

<bean id="singletonBean" class="com.itxxz.HelloItxxz"> <constructor-arg> <value>Hello! 这是singletonBean!value> </constructor-arg> </bean>

③工厂方法:

public class StaticFactoryBean { public static Integer createRandom() { return new Integer(new Random().nextInt()); } } .... <bean id="random" class="example.chapter3.StaticFactoryBean" factory-method="createRandom" />

④代理模式:在aop中有体现,比如Jdk动态代理和Cglib子类代理;
⑤适配器模式:SpringMVC中的适配器HandlerAdatper;
⑥包装器模式:Spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator;
⑦观察者模式:Spring中Observer模式常用的地方是listener的实现。如ApplicationListener;
⑧模板方法模式:Spring中的JdbcTemplate;
⑨策略模式:;

详细参考一:
https://mp.weixin.qq.com/s/kwgV7Rhxv7wV7DOWmS9NzQ
参考二:
https://www.cnblogs.com/AndyAo/p/8666385.html


1. Spring中Bean生命周期?

谈谈你对Spring Bean生命周期的理解【面试】):https://blog.csdn.net/cool_summer_moon/article/details/106149339

详细参考:https://www.jianshu.com/p/1dec08d290c1
只有四个!
实例化 -> 属性赋值 -> 初始化 -> 销毁!
是的,Spring Bean的生命周期只有这四个阶段。把这四个阶段和每个阶段对应的扩展点糅合在一起虽然没有问题,但是这样非常凌乱,难以记忆。要彻底搞清楚Spring的生命周期,首先要把这四个阶段牢牢记住。实例化和属性赋值对应构造方法和setter方法的注入,初始化和销毁是用户能自定义扩展的两个阶段。在这四步之间穿插的各种扩展点,稍后会讲
1、实例化 Instantiation
2、属性赋值 Populate
3、初始化 Initialization
4、销毁 Destruction
实例化 -> 属性赋值 -> 初始化 -> 销毁!
主要逻辑都在doCreate()方法中,逻辑很清晰,就是顺序调用以下三个方法,这三个方法与三个生命周期阶段一一对应,非常重要,在后续扩展接口分析中也会涉及。
1、createBeanInstance() -> 实例化
2、populateBean() -> 属性赋值
3、initializeBean() -> 初始化

至于销毁,是在容器关闭时调用的,详见ConfigurableApplicationContext#close();


1. 为什么要使用 Spring?

2. 解释一下什么是 AOP?

项目应用实例(使用AOP实现自定义日志):https://blog.csdn.net/qq_41029923/article/details/120503841
项目应用实例(Redisson分布式锁的实现):https://blog.csdn.net/qq_41029923/article/details/120512744

AOP详情参考:https://blog.csdn.net/qq_33369905/article/details/105828920?spm=1001.2014.3001.5501

SpringAOP底层的实现原理是 JDK动态代理的方式实现:使用 JDK API动态的在内存中创建代理对象;
IOC控制反转用的是 Java的反射机制注入的;
MyBatis为什么没有实现接口的类就可以调用接口中的方法?:MyBatis通过动态代理的方式实现了只通过 mapper接口而无接口的实现类的方式操作数据库;

Spring使用AOP实现事务控制:
配置事务管理器、事务通知、AOP:

<aop:config> <aop:pointcut id="pt1" expression="execution(* com.jiading.service.impl.*.*(..))"/> <aop:aspect id="txAdvice" ref="txManager"> <aop:before pointcut-ref="pt1" method="beginTransaction"></aop:before> <aop:after pointcut-ref="pt1" method="commit"></aop:after> <aop:after-throwing pointcut-ref="pt1" method="rollback"></aop:after-throwing> <aop:after-returning pointcut-ref="pt1" method="release"></aop:after-returning> </aop:aspect> </aop:config>

详情参考:https://www.cnblogs.com/jiading/p/12368832.html

AOP 用处:事务、日志、异常等

在软件开发过程中,跨越应用程序多个点的功能称为交叉问题。这些交叉问题与应用程序的主要业务逻辑不同。因此,将这些横切关注与业务逻辑分开是面向方面编程(AOP)的地方。
问题:Spring AOP的代理是什么?
Spring AOP是基于代理实现的,默认为标准的 JDK 动态代理。这使得任何接口(或者接口的集合)可以被代理。
Spring AOP 也使用 CGLIB 代理。如果业务对象没有实现任何接口那么默认使用CGLIB。

3. 解释一下什么是 IOC?

4. Spring有哪些模块?

5. Spring常用的注入方式有哪些?

//一、使用构造方法注入 //有<bean id="" class="">必须要有无参构方 //使用constructor属性标签是时,必须要有带参构方 <bean id="car" class="com.asd.Car"> <constructor-arg index="0" value="黑色"/> <constructor-arg index="1" value="白色"/> <constructor-arg name="color" value="黑色"/> <constructor-arg name="brand" value="benz"/> </bean> //二、使用setter属性注入 //此方式时最常用的;有property属性标签,类中必须有对应的set方法 <bean id="car2" class="com.asd.Car"> <property name="color" value="黑色"/> <property name="brand" value="benz"/> </bean>

三、使用注解方法注入:
@Component:bean注入
@Respository:持久层dao
@Service:service层
@Controller
@Resource:属性注入

//Controller层 @Controller @RequestMapping("/admin") public class AdminController { @Autowired private AdminServiceImpl adminServiceImpl; @RequestMapping("/adminRegist") //管理员注册 public void adminRegist(Admin admin,HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException { adminServiceImpl.insertInstance(admin); req.getRequestDispatcher("/manage_login.jsp").forward(req, resp); } } //Service层 @Service public class AdminServiceImpl extends CommonServiceImpl<Admin> { @Autowired private AdminDao adminDao; public void insertInstance(Admin admin) { adminDao.insertAdmin(admin); } public Admin findInstance(int id) { return adminDao.findAdmin(id); } } //Dao层 public interface AdminDao { void insertAdmin(Admin admin); //添加管理员信息 void deleteAdmin(int id); //根据id删除管理员信息 void updateAdmin(Admin admin) ;//修改管理员信息 } // xml文件中开启注解扫描 <context:component-scan base-package="com.asd"/>

测试时:AppTest.java中
① 先通过配置文件得到IOC容器 applicationContext;
② 再从容器 applicationContext.getBean(“bean的id值”) 获取 bean对象;

public class AppTest { private ApplicationContext applicationContext; @Before public void init(){ applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml"); } @Test public void Test1(){ User user1= (User) applicationContext.getBean("user1"); System.out.println(user1); } }

5_1. Spring IOC的三种注入方式:

【1】构造器注入:
【2】setter注入:
【3】接口注入:

//构造器注入 public class A{ private Admin admin; public A(Admin admin){ this.admin=admin; } } //setter注入 public class A{ private Admin admin; public void setAdmin(Admin admin){ this.admin=admin; } } //接口注入 public interface Admin{ public void Admin(User user); } public class A{ private User user; public void Admin(User user){ this.user=user; } }

5_2. Spring中的 bean是线程安全吗?

5_3. Spring中的 bean默认是单例模式吗?

Spring中的 bean默认是单例模式的,配置文件中创建bean对象时可修改。
单例:scope值为 singleton、或者不写时默认单例 ;scope值改为 prototype表示多例;
懒加载:lazy-init 值为 default、false时默认不延迟(懒)加载;lazy-init值为 true时表示启用懒加载;

init-method、destory-method是类中自带的方法的方法名:eg:

<bean id="user" class="com.asd.User" scope="singleton" lazy-init="default" init-method="init_user" destory-method="destory_user"/>

6. Spring支持几种 bean的作用域?

7. Spring自动装配 bean的方式有哪些?

8. Spring容器创建对象的几种方式?

1、调用无参的构造方法;(只要有下面这句,类中就要有无参构方)eg:
<bean id="user" class="com.asd.User"></bean>
2、调用带参的构造方法;

<bean id="car" class="com.asd.Car"> <constructor-arg index="0" value="黑色"/> <constructor-arg index="1" value="白色"/> <constructor-arg name="color" value="黑色"/> <constructor-arg name="brand" value="benz"/> </bean>

3、使用工厂类创建对象;

//使用工厂类非静态方法创建对象(先创建工厂类的bean实例,再通过id值去引用) <bean id="userFactory" class="com.asd.UserFactory"/> <bean id="user1" factory-bean="userFactory" factory-method="getInstance"/> //使用工厂类静态方法创建对象 <bean id="user2" class="com.asd.UserFactory" factory-method="getStaticInstance"/>

9. Spring中动态代理

代理:可理解为在不修改目标对象的前提下对目标对象进行扩展

【1】静态代理:
要求:代理对象与目标对象实现同样的接口;
优点:可以做到在不修改目标对象的前提下对目标对象进行扩展
缺点:因为代理对象与目标对象实现相同的接口,会有很对代理类,一旦接口中增加方法,目标对象与代理对象都需要维护;
解决方式:用代理工厂即使用动态代理;
【2】动态代理(也叫JDK动态代理、JDK代理、接口代理) 与 cglib代理(也叫子类代理)
动态代理:目标对象(即类)要实现接口,代理对象不需要实现接口,在内部自动帮忙实现接口,使用到 JDKAPI动态的在内存中创建代理对象(所以又叫接口代理、JDK代理)。使用到 API中 Proxy提供的 newProxyInstance( )方法:三个参数:

target.getClass.getClassLoader(),//目标对象的类加载器 target.getClass.getInterface(), //目标对象的接口类型 new InvocationHandler(){ //事件处理器 ... }

【3】cglib代理:又叫子类代理,在内存中构建一个子类对象,实现对目标对象的扩展;要求:
① 目标对象(即类)不能是 final,否则会报错;
② 目标对象的方法是 final、static时,则不会拦截此方法(即添加的扩展内容无法得到)

在 SprigAOP编程中:(自动选择)
若加入容器的目标对象有实现接口,用动态代理;
若加入容器的目标对象没有实现接口且目标对象不是 final,用 cglib代理;

详细参考:https://blog.csdn.net/quge_name_harder/article/details/83304287

AspectJ 实现 AOP

注解:@Component、@Aspect;@Before、@After、@AfterReturnning、@AfterThrowing、@Around

【 切面类 】:@Component、@Aspect
【 切入点表达式 】
书写方式:

@Pointcut("execution(public void com.asd.Dao.UserDao.save())") //@Pointcut("execution(* *.*())") public void pointCut(){}

方式一:写全部,用execution表达式:@Before(“execution(public void com.asd.Dao.UserDao.save())”)
方式二:直接使用声明好的@Pointcut():@Before(“pointCut()”)

//1、@Before业务代码之前 @Before("execution(public void com.asd.Dao.UserDao.save())") //@Before("pointCut()") public void beginTrans(){ System.out.println("开始事务"); } //2、@After业务代码之后,无论有无异常都执行 @After("execution(访问修饰 返回类型 类的全限定名 方法名(参数))") //@After("pointCut()") public void commitTrans(){ System.out.println("提交事务"); } //3、@AfterReturnning当返回结果后作执行,若出现异常不执行此方法 //方式一 @AfterReturnning("execution(* *.*(..))") public void afterReturnning(){ System.out.println("AfterReturnning"); } //方式二 :returning表参数,value表切入点 @AfterReturnning(returning="value",value="pointCut()") public void returnTest(Object value){ System.out.println("AfterThrowing"); } //4、@AfterThrowing出现异常执行此方法 //方式一 @AfterThrowing("execution(* *.*(..))") public void afterThrowing(){ System.out.println("AfterThrowing"); } //方式二 @AfterThrowing(value="cutPointA()",throwing="e") public void throwTest(Throwable e){ System.out.println("异常信息:"+e.toString()); } //5、@Around此方法有参数,此参数相当于业务对象,同时"joinPoint.proceed()"相当于调用核心方法(即UserDao.save()) @Around("execution(* *.*(..))") public void round(Proceeding JoinPoint joinPoint)throws Throwable{ System.out.println("begin"); joinPoint.proceed(); System.out.println("end"); }
http://www.jsqmd.com/news/500066/

相关文章:

  • 号码核验在B端拓客中的应用困境与技术升级路径研究氪迹科技法人号码核验系统
  • 软件开发常用工具介绍
  • HTTP 消息:解析与优化
  • LoRA 与 QLoRA
  • Zabbix6.2利用模板和自定义监控项监控华为AR3260路由器
  • ROS2学习记录009-使用面向对象方式编写ROS2节点
  • 从此告别拖延!全场景通用的AI论文工具 —— 千笔写作工具
  • 震惊,杨幂的脸竟然出现在了她的身体上
  • java基础学习3(数据类型转换、运算符)
  • 把坑都踩完了,千笔AI VS 笔捷Ai,全场景通用AI论文网站!
  • 【常见错误】Xilinx Vivado自带编辑器文字部分出现乱码解决办法
  • 数字孪生国内外发展现状
  • 【Xilinx Vivado时序分析/约束系列2】FPGA开发时序分析/约束-建立时间
  • 终极指南:使用Google Map React库快速构建交互式地图应用
  • JetBrains 插件 IDE设置
  • 学霸同款!全领域适配的论文神器 —— 千笔
  • STM32-串口使用注意事项
  • Kubernetes 认证通关指南:CKA/CKS/CKAD 最新题库 + 本地仿真环境 + 模拟考
  • 2.postman断言
  • 具身智能中 Wrapper 架构的深度解构与 Python 实战
  • 深度解析 | 2026新范式:当“Token”取代比特币,成为真正的数字石油
  • 李南左日更3327:为什么员工都在摸鱼?是因为你曾经不信任他们
  • 终极Git与GitHub教程:从零开始掌握版本控制的完整指南
  • 【Xilinx Vivado时序分析/约束系列3】FPGA开发时序分析/约束-保持时间
  • 2026年靠谱的孝感钻井厂家推荐:十堰钻井/养殖场钻井公司精选 - 品牌宣传支持者
  • # 发散创新:用Go语言高效接入InfluxDB实现时序数据采集与可视化在现代微服务架构中,**时序数据
  • 【Xilinx Vivado时序分析/约束系列4】FPGA开发时序分析/约束-实验工程上手实操
  • 终极指南:如何快速掌握JEnv进行Java环境管理
  • reCAPTCHA PHP错误代码完全解析:快速定位和解决验证问题
  • 关于旧系统+旧安卓版本realme手机的原生文件管理不支持向微信好友一次性发送多个非照片格式文件的问题和解决方案