一、Spring

发布时间:2026/5/24 21:33:59

一、Spring 一、Spring0. Spring事务二、Spring事务1. Spring如何解决循环依赖的问题详情参考https://blog.csdn.net/qq_36381855/article/details/79752689即A依赖BB依赖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.html1. Spring中用到的设计模式有哪些Spring 中经典的 9 种设计模式单例模式、工厂模式简单工厂、工厂方法、代理模式、适配器模式、包装器模式装饰器模式、观察者模式、模板方法模式、策略模式等①单例模式scope值为 singleton、或者不写时默认单例 scope值改为 prototype表示多例singleton“true|false” 或者 scope“singleton|prototype”来指定②简单工厂bean idsingletonBean classcom.itxxz.HelloItxxz constructor-arg valueHello! 这是singletonBean!value /constructor-arg /bean③工厂方法public class StaticFactoryBean { public static Integer createRandom() { return new Integer(new Random().nextInt()); } } .... bean idrandom classexample.chapter3.StaticFactoryBean factory-methodcreateRandom /④代理模式在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.html1. 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、实例化 Instantiation2、属性赋值 Populate3、初始化 Initialization4、销毁 Destruction实例化 - 属性赋值 - 初始化 - 销毁主要逻辑都在doCreate()方法中逻辑很清晰就是顺序调用以下三个方法这三个方法与三个生命周期阶段一一对应非常重要在后续扩展接口分析中也会涉及。1、createBeanInstance() - 实例化2、populateBean() - 属性赋值3、initializeBean() - 初始化至于销毁是在容器关闭时调用的详见ConfigurableApplicationContext#close()1. 为什么要使用 Spring2. 解释一下什么是 AOP项目应用实例使用AOP实现自定义日志https://blog.csdn.net/qq_41029923/article/details/120503841项目应用实例Redisson分布式锁的实现https://blog.csdn.net/qq_41029923/article/details/120512744AOP详情参考https://blog.csdn.net/qq_33369905/article/details/105828920?spm1001.2014.3001.5501SpringAOP底层的实现原理是 JDK动态代理的方式实现使用 JDK API动态的在内存中创建代理对象IOC控制反转用的是 Java的反射机制注入的MyBatis为什么没有实现接口的类就可以调用接口中的方法MyBatis通过动态代理的方式实现了只通过 mapper接口而无接口的实现类的方式操作数据库Spring使用AOP实现事务控制配置事务管理器、事务通知、AOP:aop:config aop:pointcut idpt1 expressionexecution(* com.jiading.service.impl.*.*(..))/ aop:aspect idtxAdvice reftxManager aop:before pointcut-refpt1 methodbeginTransaction/aop:before aop:after pointcut-refpt1 methodcommit/aop:after aop:after-throwing pointcut-refpt1 methodrollback/aop:after-throwing aop:after-returning pointcut-refpt1 methodrelease/aop:after-returning /aop:aspect /aop:config详情参考https://www.cnblogs.com/jiading/p/12368832.htmlAOP 用处事务、日志、异常等在软件开发过程中跨越应用程序多个点的功能称为交叉问题。这些交叉问题与应用程序的主要业务逻辑不同。因此将这些横切关注与业务逻辑分开是面向方面编程AOP的地方。问题Spring AOP的代理是什么Spring AOP是基于代理实现的默认为标准的 JDK 动态代理。这使得任何接口或者接口的集合可以被代理。Spring AOP 也使用 CGLIB 代理。如果业务对象没有实现任何接口那么默认使用CGLIB。3. 解释一下什么是 IOC4. Spring有哪些模块5. Spring常用的注入方式有哪些//一、使用构造方法注入 //有bean id class必须要有无参构方 //使用constructor属性标签是时必须要有带参构方 bean idcar classcom.asd.Car constructor-arg index0 value黑色/ constructor-arg index1 value白色/ constructor-arg namecolor value黑色/ constructor-arg namebrand valuebenz/ /bean //二、使用setter属性注入 //此方式时最常用的有property属性标签类中必须有对应的set方法 bean idcar2 classcom.asd.Car property namecolor value黑色/ property namebrand valuebenz/ /bean三、使用注解方法注入Componentbean注入Respository持久层daoServiceservice层ControllerResource属性注入//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 CommonServiceImplAdmin { 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-packagecom.asd/测试时AppTest.java中① 先通过配置文件得到IOC容器 applicationContext② 再从容器 applicationContext.getBean(“bean的id值”) 获取 bean对象public class AppTest { private ApplicationContext applicationContext; Before public void init(){ applicationContextnew 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.adminadmin; } } //setter注入 public class A{ private Admin admin; public void setAdmin(Admin admin){ this.adminadmin; } } //接口注入 public interface Admin{ public void Admin(User user); } public class A{ private User user; public void Admin(User user){ this.useruser; } }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是类中自带的方法的方法名egbean iduser classcom.asd.User scopesingleton lazy-initdefault init-methodinit_user destory-methoddestory_user/6. Spring支持几种 bean的作用域7. Spring自动装配 bean的方式有哪些8. Spring容器创建对象的几种方式1、调用无参的构造方法只要有下面这句类中就要有无参构方egbean iduser classcom.asd.User/bean2、调用带参的构造方法bean idcar classcom.asd.Car constructor-arg index0 value黑色/ constructor-arg index1 value白色/ constructor-arg namecolor value黑色/ constructor-arg namebrand valuebenz/ /bean3、使用工厂类创建对象//使用工厂类非静态方法创建对象(先创建工厂类的bean实例再通过id值去引用) bean iduserFactory classcom.asd.UserFactory/ bean iduser1 factory-beanuserFactory factory-methodgetInstance/ //使用工厂类静态方法创建对象 bean iduser2 classcom.asd.UserFactory factory-methodgetStaticInstance/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/83304287AspectJ 实现 AOP注解Component、AspectBefore、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(returningvalue,valuepointCut()) public void returnTest(Object value){ System.out.println(AfterThrowing); } //4、AfterThrowing出现异常执行此方法 //方式一 AfterThrowing(execution(* *.*(..))) public void afterThrowing(){ System.out.println(AfterThrowing); } //方式二 AfterThrowing(valuecutPointA(),throwinge) 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); }

相关新闻