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

深圳 网站制作 哪家wordpress获取自定义字段的值

深圳 网站制作 哪家,wordpress获取自定义字段的值,h5制作多少钱,自己的公众号怎么做的目录 1. 为什么要使用 spring#xff1f; 2. 解释一下什么是 Aop#xff1f; 3. AOP有哪些实现方式#xff1f; 4. Spring AOP的实现原理 5. JDK动态代理和CGLIB动态代理的区别#xff1f; 6. 解释一下什么是 ioc#xff1f; 7. spring 有哪些主要模块#xff1f;…目录 1. 为什么要使用 spring 2. 解释一下什么是 Aop 3. AOP有哪些实现方式 4. Spring AOP的实现原理 5. JDK动态代理和CGLIB动态代理的区别 6. 解释一下什么是 ioc 7. spring 有哪些主要模块 8. spring 常用的注入方式有哪些 9. spring 中的 bean 是线程安全的吗 10. spring 支持几种 bean 的作用域 11. spring 自动装配 bean 有哪些方式 12. spring 事务实现方式有哪些 13. 说一下 spring 的事务隔离 14. 说一下 spring mvc 运行流程 15. spring mvc 有哪些组件 16. RequestMapping 的作用是什么 17. Autowired 的作用是什么 18. Spring有哪些事务传播行为 19. Spring事务在什么情况下会失效 20. Spring怎么解决循环依赖的问题 21. Spring启动过程 22. Spring 的单例 Bean 是否有并发安全问题 23. Spring Bean如何保证并发安全 24. springbean的生命周期 25. springboot注解 26. SpringBootApplication注解 26.1. ComponentScan 26.2. SpringBootConfiguration 26.3. EnableAutoConfiguration 26.3.1. AutoConfigurationPackage 26.3.1.1. Import(AutoConfigurationPackages.Registrar.class) 26.4. Import(AutoConfigurationImportSelector.class) 1. 为什么要使用 spring 通过IOC控制反转和DI依赖注入实现松耦合。支持AOP面向切面的编程并且把应用业务逻辑和系统服务分开。通过切面和模板减少样板式代码。声明式事务的支持。可以从单调繁冗的事务管理代码中解脱出来通过声明式方式灵活地进行事务的管理提高开发效率和质量。方便集成各种优秀框架。内部提供了对各种优秀框架的直接支持如Hessian、Quartz、MyBatis等。方便程序的测试。Spring支持Junit4添加注解便可以测试Spring程序。 2. 解释一下什么是 Aop AOPAspect-Oriented Programming面向切面编程是一种编程范式AOP的核心思想是通过将这些横切关注点从业务逻辑中分离出来并将其定义为独立的模块称为切面。切面可以在整个应用程序中重用他以提供特定的横切关注点的功能如日志记录、事务管理等。AOP通过定义和应用横切关注点来解决应用程序中的横切关注点的分离和抽象问题。 在传统的面向对象编程中业务逻辑通常以类的形式组织每个类负责实现特定的功能。然而某些关注点例如日志记录、事务管理、安全性检查可能存在于整个应用程序中并且会横跨多个类和模块。将这些关注点耦合到每个类中会导致代码的重复和难以维护。 AOP使用通知Advice来表示切面的具体行为通知指定在连接点处插入切面的时机例如方法执行前、后等。通知的类型包括前置通知在连接点之前执行、后置通知在连接点之后执行、返回通知在连接点成功返回后执行、异常通知在连接点抛出异常时执行和环绕通知在连接点前后执行。 织入Weaving是将切面应用到目标对象中的过程。织入可以在编译时、运行时或者在系统启动时进行。织入可以通过编译器、特定的AOP框架或者动态代理实现。 AOP的优势在于解决了关注点分离和重用性的问题提高了代码的模块化程度和可维护性。它能够降低代码的复杂性减少了重复代码的编写并实现了关注点的集中管理。AOP在众多框架和技术中被广泛应用最著名的是Spring框架它提供了强大的AOP支持 横切关注点横切关注点Cross-cutting Concerns指的是那些在应用程序中存在于多个模块或组件中与核心业务逻辑无关但却需要在不同的地方进行处理的功能或特性。 横切关注点不属于应用程序核心业务逻辑但是它们对于应用程序的正确性、可靠性、安全性和性能等方面至关重要 3. AOP有哪些实现方式 AOP有两种实现方式静态代理和动态代理。 静态代理 静态代理代理类在编译阶段生成在编译阶段将通知织入Java字节码中也称编译时增强。AspectJ使用的是静态代理。 缺点代理对象需要与目标对象实现一样的接口并且实现接口的方法会有冗余代码。同时一旦接口增加方法目标对象与代理对象都要维护。 动态代理 动态代理代理类在程序运行时创建AOP框架不会去修改字节码而是在内存中临时生成一个代理对象在运行期间对业务方法进行增强不会生成新类。 4. Spring AOP的实现原理 Spring的AOP实现原理其实很简单就是通过动态代理实现的。如果我们为Spring的某个bean配置了切面那么Spring在创建这个bean的时候实际上创建的是这个bean的一个代理对象我们后续对bean中方法的调用实际上调用的是代理类重写的代理方法。而Spring的AOP使用了两种动态代理分别是JDK的动态代理以及CGLib的动态代理 5. JDK动态代理和CGLIB动态代理的区别 Spring AOP中的动态代理主要有两种方式JDK动态代理和CGLIB动态代理。 JDK动态代理 如果目标类实现了接口Spring AOP会选择使用JDK动态代理目标类。代理类根据目标类实现的接口动态生成不需要自己编写生成的动态代理类和目标类都实现相同的接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。 缺点目标类必须有实现的接口。如果某个类没有实现接口那么这个类就不能用JDK动态代理。 GLIB动态代理 通过继承实现。如果目标类没有实现接口那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIBCode Generation Library可以在运行时动态生成类的字节码动态创建目标类的子类对象在子类对象中增强目标类。 CGLIB是通过继承的方式做的动态代理因此如果某个类被标记为final那么它是无法使用CGLIB做动态代理的。 优点目标类不需要实现特定的接口更加灵活。 什么时候采用哪种动态代理 如果目标对象实现了接口默认情况下会采用JDK的动态代理实现AOP如果目标对象实现了接口可以强制使用CGLIB实现AOP如果目标对象没有实现了接口必须采用CGLIB库 两者的区别 jdk动态代理使用jdk中的类Proxy来创建代理对象它使用反射技术来实现不需要导入其他依赖。cglib需要引入相关依赖asm.jar它使用字节码增强技术来实现。当目标类实现了接口的时候Spring Aop默认使用jdk动态代理方式来增强方法没有实现接口的时候使用cglib动态代理方式增强方法。 6. 解释一下什么是 ioc IOCInversion of Control控制反转它将程序中对象之间的依赖关系的创建和绑定由应用程序自身转移到了外部容器来处理。这个外部容器通常是一个框架 在传统的编程模型中应用程序负责创建和管理对象之间的依赖关系。这种方式把对象的控制权交给了应用程序使得对象之间的依赖关系紧密耦合难以管理和扩展。 而IOC就是将这种控制权反转过来将对象创建和依赖关系的处理交由外部容器负责。应用程序只需定义对象的依赖关系而不用负责对象的创建和装配。容器根据配置信息自动创建和管理对象的实例并将依赖关系注入到相应的对象中。这样就实现了控制的反转。 IOC的核心概念是依赖注入Dependency InjectionDI。依赖注入是指容器动态地将依赖关系注入到对象中而不是通过对象自身去创建或查找依赖对象。通过依赖注入对象可以通过接口或者特定的注解来声明它所依赖的其他对象容器根据这些声明来自动装配所需的依赖。 IOC的优势在于解耦对象之间的依赖关系减少了对象间的紧密耦合提高了代码的可扩展性和可维护性。它简化了对象的创建和管理过程减少了重复的代码并提高了代码的可测试性。 Spring框架是IOC的一种重要实现它提供了强大的依赖注入功能让开发者能够充分利用IOC原则来构建松耦合、可扩展和易于测试的应用程序。 7. spring 有哪些主要模块 Spring框架包含了很多不同的模块每个模块都提供了独特的功能和特性可以根据需要进行选择和使用。以下是Spring框架的一些主要模块 Spring CoreSpring核心模块提供了IoC容器和依赖注入的基本功能。它包括Bean容器、Bean的生命周期管理、依赖注入等核心特性。Spring MVCSpring MVC是一个基于模型-视图-控制器Model-View-Controller的Web框架。它提供了处理Web请求和生成响应的功能帮助构建灵活且可扩展的Web应用程序。Spring DataSpring Data模块提供了对数据访问的支持。它简化了与各种数据存储技术如关系型数据库、NoSQL数据库、键值对存储等进行交互的过程提供了统一的数据访问接口和便捷的数据操作功能。Spring SecuritySpring Security是一个功能强大的安全框架用于保护应用程序的安全性。它提供了身份验证、授权、密码加密、会话管理等功能可以轻松集成到Spring应用程序中。Spring AOPSpring AOPAspect-Oriented Programming模块提供了面向切面编程的支持。它通过将横切关注点例如日志记录、性能监控、事务管理等从核心业务逻辑中分离出来实现了更好的模块化和可重用性。Spring BatchSpring Batch是一个处理大量数据和批量作业的框架。它提供了可重用的组件和模式用于构建和执行批处理任务例如数据导入/导出、报表生成、批量处理任务等。Spring IntegrationSpring Integration是一个用于构建企业集成系统的框架。它通过提供丰富的消息处理机制和适配器使得不同系统之间的通信变得更加简单和可靠。 8. spring 常用的注入方式有哪些 在Spring框架中有多种常用的依赖注入Dependency Injection, DI方式。以下是一些常见的注入方式 构造函数注入Constructor Injection通过构造函数将依赖项注入到目标对象中。可以通过构造函数参数来明确指定依赖项从而在创建对象时自动完成注入。Setter方法注入Setter Injection使用Setter方法来设置依赖项。通过定义公开的Setter方法并在容器配置中使用属性注入property injection来注入依赖项。字段注入Field Injection使用注解直接在字段上进行注入。通过在目标类的成员变量上标记注解如Autowired来实现自动注入。方法注入Method Injection使用特定注解标记的方法来完成依赖项的注入。可以在方法的参数上使用注解或通过配置方式来指定依赖项。接口注入Interface Injection通过实现特定接口在接口方法中进行依赖项的注入。但这种方式相对较少使用因为它引入了对特定接口的依赖。 9. spring 中的 bean 是线程安全的吗 在Spring框架中默认情况下每个bean实例都是单例的这意味着默认情况下Spring的bean不是线程安全的。当多个线程同时访问同一个bean实例时存在并发访问的风险。 线程安全这个问题要从单例与原型Bean分别进行说明 单例模式Singleton默认情况下Spring的bean是单例的由Spring容器负责创建和管理。对于单例Bean,所有线程都共享一个单例实例Bean,因此是存在资源的竞争。原型模式Prototype通过配置bean的作用域为prototype可以每次请求时都创建一个新的bean实例。对于原型Bean,每次创建一个新对象也就是线程之间并不存在Bean共享自然是不会有线程安全的问题。线程作用域Thread ScopeSpring还提供了线程作用域Thread Scope的支持可以使用ThreadLocal实现每个线程拥有独立的bean实例。这样每个线程都可以独立地操作自己的bean实例实现了线程间的隔离和线程安全。 如果需要保证Spring的bean的线程安全性可以在bean的实现中采取一些线程安全的措施比如使用同步synchronized关键字、使用线程安全的集合或使用线程安全的设计模式根据具体的业务需求进行选择。 总之Spring的bean是否线程安全取决于其实现方式和具体的配置开发人员需要在设计和实现bean时注意线程安全的问题并根据实际情况选择合适的解决方案。 10. spring 支持几种 bean 的作用域 Spring框架支持以下常见的Bean作用域 Singleton默认每个Spring容器中只会存在一个Bean实例。在整个应用程序中无论多少次请求获取该Bean都将返回同一个实例。Prototype每次通过容器的getBean()方法获取Bean时都会创建一个新的Bean实例。每次注入或请求该Bean时都会得到一个独立的实例。Request在一次HTTP请求过程中创建一个Bean实例该实例为当前请求提供服务。不同的请求将获得不同的Bean实例。Session在一个HTTP会话期间创建一个Bean实例该实例与该会话相关联。在会话期间不同的请求将共享同一个会话Bean实例。Global Session在基于Portlet的Web应用程序中该作用域与Session作用域类似但全局会话是面向所有Portlet请求的共享实例。Application在整个Web应用程序的生命周期内创建一个Bean实例。多个请求将共享同一个应用程序作用域的Bean实例。WebSocket在WebSocket会话期间创建一个Bean实例该实例与WebSocket会话相关联。WebSocket会话期间不同的请求将共享同一个WebSocket Bean实例。 以上是Spring框架中常用的Bean作用域。可以根据应用程序的不同需求选择合适的作用域在配置Bean时使用Scope注解或XML配置文件中的bean元素设定作用域。 11. spring 自动装配 bean 有哪些方式 默认方式使用注解Autowired进行自动装配。Spring会根据类型进行自动装配当有多个同类型的Bean时可以使用Qualifier指定具体的Bean名称。 Autowired private MyBean myBean; 通过构造函数进行自动装配使用Autowired注解可以直接将依赖注入到构造函数中。 Autowired public MyClass(MyBean myBean) {this.myBean myBean; } 通过setter方法进行自动装配使用Autowired注解可以将依赖注入到setter方法中。 Autowired public void setMyBean(MyBean myBean) {this.myBean myBean; } 使用Resource注解进行自动装配Resource注解是JavaEE提供的Spring也支持它。它可以根据Bean的名称自动注入依赖。 Resource private MyBean myBean; 通过Inject注解进行自动装配与Autowired类似Inject也可以实现自动装配。 Inject private MyBean myBean; 所有这些方式都可以与Qualifier一起使用用于指定精确的Bean名称进行装配。 除了上述方式Spring还提供了基于XML配置文件的自动装配方式。在XML文件中可以使用context:component-scan元素激活自动扫描并使用bean元素声明BeanSpring会根据规则自动装配这些Bean。 总结Spring提供了多种方式来实现自动装配Bean包括注解AutowiredQualifierResourceInject和XML配置文件的方式。这些方式都可以根据类型或名称进行自动装配提高了开发效率和代码的可读性 12. spring 事务实现方式有哪些 事务就是一系列的操作原子执行。Spring事务机制主要包括声明式事务和编程式事务。 基于注解的声明式事务管理使用Transactional注解来标识需要进行事务管理的方法或类。通过在方法或类上添加该注解Spring会自动处理事务的开始、提交、回滚等操作。 Service Transactional public class UserServiceImpl implements UserService {// ... } 基于编程式事务管理使用编程的方式在代码中进行事务管理通过编写事务管理的代码块来控制事务的开始、提交、回滚等操作。 Autowired private PlatformTransactionManager transactionManager;Transactional public void performOperation() {TransactionStatus status transactionManager.getTransaction(new DefaultTransactionDefinition());try {// 执行业务逻辑操作// ...transactionManager.commit(status);} catch (Exception e) {transactionManager.rollback(status);throw e;} } 基于XML配置的声明式事务管理通过在XML配置文件中进行事务管理的配置。需要配置事务管理器、事务通知等相关元素。 bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManagerproperty namedataSource refdataSource / /beantx:advice idtxAdvice transaction-managertransactionManagertx:attributestx:method name* propagationREQUIRED //tx:attributes /tx:adviceaop:configaop:pointcut idtransactionPointcut expressionexecution(* com.example.service.*.*(..)) /aop:advisor advice-reftxAdvice pointcut-reftransactionPointcut / /aop:config 13. 说一下 spring 的事务隔离 Spring框架提供了对事务隔离级别的支持事务隔离级别定义了事务之间的隔离程度。以下是Spring框架支持的事务隔离级别 DEFAULT使用数据库默认的隔离级别。READ_UNCOMMITTED读未提交事务可以读取其他事务尚未提交的数据可能导致脏读、不可重复读和幻读问题。READ_COMMITTED读已提交事务只能读取其他事务已经提交的数据可以解决脏读问题但可能产生不可重复读和幻读问题。REPEATABLE_READ可重复读事务在整个过程中可以多次读取相同的数据保证了一致性读取可以解决脏读和不可重复读问题但可能产生幻读问题。SERIALIZABLE串行化事务按照顺序逐个执行事务之间是串行化的可以避免脏读、不可重复读和幻读问题但性能较差。 在Spring中通过Transactional注解的isolation属性来设置事务隔离级别。例如 Transactional(isolation Isolation.READ_COMMITTED) public void performOperation() {// ... } 需要注意的是事务隔离级别的选择应根据具体的业务需求和并发情况来进行合理的评估。较高的隔离级别可以提供更高的数据一致性但会带来一定的性能开销。开发人员应根据具体情况选择适当的隔离级别。 注 脏读Dirty Read脏读指的是一个事务读取了另一个事务未提交的数据。当一个事务读取到了另一个事务修改过但未提交的数据时如果该修改操作回滚那么读取到的数据就是无效的称为脏读。读到了另一个事务提交之前的修改过的数据 不可重复读Non-repeatable Read不可重复读指的是在同一个事务内多次读取同一数据时得到的结果不一致。例如事务A在一个数据记录上执行了读取操作然后事务B对该数据记录执行了更新操作并提交接着事务A再次读取该数据记录时得到的结果与前一次读取的结果不一样。读取同一个数据的结果不一样 幻读Phantom Read幻读指的是在同一个事务内多次执行同样的查询操作得到了不同数量的结果。例如事务A在一个数据表上执行了一个范围查询例如SELECT * FROM table WHERE condition接着事务B在该表中插入了一行符合事务A的查询条件的数据并提交接着事务A再次执行同样的查询时得到的结果集数量发生了变化。 同样的操作读到数据不一样 这些问题都是由于事务并发和隔离级别低导致的。为了解决这些问题可以使用数据库的事务隔离级别 读未提交Read Uncommitted最低的事务隔离级别允许脏读、不可重复读和幻读。读已提交Read Committed允许不可重复读和幻读但不允许脏读。可重复读Repeatable Read允许幻读但不允许脏读和不可重复读。MySQL的默认隔离级别。串行化Serializable最高的事务隔离级别禁止脏读、不可重复读和幻读。 需要根据实际情况选择适当的事务隔离级别来解决并发问题。 14. 说一下 spring mvc 运行流程 客户端发送请求到DispatcherServlet前端控制器。DispatcherServlet收到请求后根据请求URL找到对应的HandlerMapping处理器映射器通过HandlerMapping确定处理请求的Handler处理器。HandlerAdapter处理器适配器将请求转发给Handler执行。Handler执行业务逻辑处理请求并返回一个ModelAndView对象。Handler将处理结果封装在ModelAndView对象中包括数据模型和视图信息。Handler返回的ModelAndView交给DispatcherServlet。DispatcherServlet调用ViewResolver视图解析器根据视图信息再次转发到具体的View视图。View视图负责渲染数据模型生成最终的HTML、JSON等响应。View将渲染结果返回给DispatcherServlet。DispatcherServlet将最终的响应返回给客户端。 15. spring mvc 有哪些组件 DispatcherServlet前端控制器它是整个Spring MVC框架的入口点负责接收客户端的请求并将请求分发给相应的处理器(Controller)。HandlerMapping处理器映射器它负责根据请求的URL找到相应的处理器(Controller)将请求映射到具体的处理器。HandlerAdapter处理器适配器它负责调用处理器(Controller)来处理请求并将处理结果封装为ModelAndView对象。ViewResolver视图解析器它负责解析视图的逻辑名称并根据名称获取实际的视图对象。View视图它负责渲染模型数据并生成最终的响应结果可以是JSP页面、HTML页面、JSON数据等。HandlerInterceptor处理器拦截器它提供了在请求处理过程中的拦截机制可以在请求前、请求后或者渲染视图之前进行特定的处理。ModelAndView模型和视图对象它封装了处理器(Controller)处理请求后的模型数据和视图名称。DataBinder数据绑定器它负责将请求参数绑定到处理器(Controller)的方法参数上实现参数的自动绑定。 16. RequestMapping 的作用是什么 RequestMapping是Spring框架中的一个注解用于将HTTP请求映射到特定的处理方法Controller的方法上。它的作用是将特定的URL路径或请求方法与相应的处理方法进行绑定以定义请求的处理逻辑。 使用RequestMapping注解可以在控制器类的方法上或整个控制器类上进行声明。在方法级别上使用RequestMapping可以针对具体的URL路径和请求方法定义不同的处理方法。在类级别上使用RequestMapping可以指定共享的基本路径从而简化具体处理方法的URL映射。 RequestMapping注解提供了细粒度的配置选项包括以下常用属性 value定义映射的URL路径可以是单个字符串或字符串数组。method指定HTTP请求方法可以是GET、POST、PUT、DELETE等。params定义请求参数的条件可指定参数名和值。headers定义HTTP请求头的条件可指定头部参数名和值。consumes定义请求的Content-Type用于限制请求的媒体类型。produces定义返回的媒体类型用于指定响应的Content-Type。 通过使用不同的属性和属性值可以根据具体需求精确地匹配请求并将其路由到相应的处理方法上进行处理。RequestMapping注解使得控制器能够根据URL和请求方法灵活地处理不同的HTTP请求并将其映射到相应的业务逻辑上。 需要注意的是从Spring 4.3版本开始RequestMapping注解被GetMapping、PostMapping、PutMapping、DeleteMapping等更具体的注解所替代以提供更清晰和简洁的语义。这些具体的注解可以直接指定HTTP请求方法避免了使用method属性。 17. Autowired 的作用是什么 Autowired 是Spring框架中的一个注解用于实现自动装配dependency injection即将相应类型的Bean注入到需要它的地方。它的作用是完成依赖关系的自动建立消除了在代码中显式进行依赖对象的创建和查找的繁琐过程。 使用 Autowired 注解可以标记在需要依赖的地方比如构造函数、成员变量、方法参数或者 Setter 方法上。当 Spring 容器创建 Bean 的时候会自动解析标记了 Autowired 的依赖然后将匹配的 Bean 实例注入到相应的位置。 作用的主要方面包括 自动装配 Bean当一个类需要依赖其他对象时可以使用 Autowired 注解将相关的 Bean 自动注入到该类中。类型匹配Autowired 注解可以根据类型进行 Bean 的匹配。当容器中存在多个符合要求的 Bean 时Spring 会尝试通过类型进行匹配。依赖注入通过 Autowired 注解可以将相关的依赖对象注入到目标对象中实现对依赖的注入管理。 不允许注nullrequire false 需要注意的是Autowired 注解默认是按照类型进行装配如果有多个匹配的 Bean可以结合使用 Qualifier 注解指定具体的 Bean 名称。另外Autowired 注解也可以和 Primary 注解一起使用表示优先选择被标注为 Primary 的 Bean 进行装配。 总之Autowired 注解简化了依赖注入的配置减少了手动装配的代码量提高了代码的可读性和可维护性。同时它使得代码与特定的实现解耦提高了应用程序的灵活性和可测试性。 18. Spring有哪些事务传播行为 REQUIRED默认如果当前存在事务则加入到当前事务中进行执行如果当前没有事务则创建一个新事务进行执行。REQUIRES_NEW无论当前是否存在事务都创建一个新的事务进行执行。如果当前存在事务则将当前事务挂起。SUPPORTS如果当前存在事务则加入到当前事务中进行执行如果当前没有事务则以非事务的方式执行。NOT_SUPPORTED以非事务的方式执行操作如果当前存在事务则将当前事务挂起。MANDATORY如果当前存在事务则加入到当前事务中进行执行如果当前没有事务则抛出异常。NEVER以非事务的方式执行操作如果当前存在事务则抛出异常。NESTED如果当前存在事务则创建一个嵌套事务并进行执行如果当前没有事务则创建一个新事务进行执行。嵌套事务可以独立提交或回滚但是必须在外部事务的边界内进行。 propagation PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别: 使用PROPAGATION_REQUIRES_NEW时内层事务与外层事务是两个独立的事务。一旦内层事务进行了提交后外层事务不能对其进行回滚。两个事务互不影响。 使用PROPAGATION_NESTED时外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚它是一个真正的嵌套事务。 19. Spring事务在什么情况下会失效 1.访问权限问题 java的访问权限主要有四种private、default、protected、public它们的权限从左到右依次变大。 如果事务方法的访问权限不是定义成public这样会导致事务失效因为spring要求被代理方法必须是public的。 翻开源码可以看到在AbstractFallbackTransactionAttributeSource类的computeTransactionAttribute方法中有个判断如果目标方法不是public则返回null即不支持事务。 protected TransactionAttribute computeTransactionAttribute(Method method, Nullable Class? targetClass) {// Dont allow no-public methods as required.if (allowPublicMethodsOnly() !Modifier.isPublic(method.getModifiers())) {return null;}... } 2. 方法用final修饰 如果事务方法用final修饰将会导致事务失效。因为spring事务底层使用了aop也就是通过jdk动态代理或者cglib帮我们生成了代理类在代理类中实现的事务功能。 但如果某个方法用final修饰了那么在它的代理类中就无法重写该方法而添加事务功能。 同理如果某个方法是static的同样无法通过动态代理变成事务方法。 3.对象没有被spring管理 使用spring事务的前提是对象要被spring管理需要创建bean实例。如果类没有加Controller、Service、Component、Repository等注解即该类没有交给spring去管理那么它的方法也不会生成事务。 4.表不支持事务 如果MySQL使用的存储引擎是myisam这样的话是不支持事务的。因为myisam存储引擎不支持事务。 5.方法内部调用 如下代码所示update方法上面没有加 Transactional 注解调用有 Transactional 注解的 updateOrder 方法updateOrder 方法上的事务会失效。 因为发生了自身调用调用该类自己的方法而没有经过 Spring 的代理类只有在外部调用事务才会生效。 Service public class OrderServiceImpl implements OrderService {public void update(Order order) {this.updateOrder(order);}Transactionalpublic void updateOrder(Order order) {// update order} } 解决方法 1、再声明一个service将内部调用改为外部调用 2、使用编程式事务 3、使用AopContext.currentProxy()获取代理对象 Servcie public class OrderServiceImpl implements OrderService {public void update(Order order) {((OrderService)AopContext.currentProxy()).updateOrder(order);}Transactionalpublic void updateOrder(Order order) {// update order}} 6.未开启事务 如果是spring项目则需要在配置文件中手动配置事务相关参数。如果忘了配置事务肯定是不会生效的。 如果是springboot项目那么不需要手动配置。因为springboot已经在DataSourceTransactionManagerAutoConfiguration类中帮我们开启了事务。 7.吞了异常 有时候事务不会回滚有可能是在代码中手动catch了异常。因为开发者自己捕获了异常又没有手动抛出把异常吞掉了这种情况下spring事务不会回滚。 如果想要spring事务能够正常回滚必须抛出它能够处理的异常。如果没有抛异常则spring认为程序是正常的。 20. Spring怎么解决循环依赖的问题 首先有两种Bean注入的方式。 构造器注入和属性注入。 对于构造器注入的循环依赖Spring处理不了会直接抛出BeanCurrentlylnCreationException异常。 对于属性注入的循环依赖单例模式下是通过三级缓存处理来循环依赖的。 而非单例对象的循环依赖则无法处理。 下面分析单例模式下属性注入的循环依赖是怎么处理的 首先Spring单例对象的初始化大略分为三步 createBeanInstance实例化bean使用构造方法创建对象为对象分配内存。populateBean进行依赖注入。initializeBean初始化bean。 Spring为了解决单例的循环依赖问题使用了三级缓存 singletonObjects完成了初始化的单例对象mapbean name -- bean instance earlySingletonObjects 完成实例化未初始化的单例对象mapbean name -- bean instance singletonFactories 单例对象工厂mapbean name -- ObjectFactory单例对象实例化完成之后会加入singletonFactories。 在调用createBeanInstance进行实例化之后会调用addSingletonFactory将单例对象放到singletonFactories中。 protected void addSingletonFactory(String beanName, ObjectFactory? singletonFactory) {Assert.notNull(singletonFactory, Singleton factory must not be null);synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}} } 假如A依赖了B的实例对象同时B也依赖A的实例对象。 A首先完成了实例化并且将自己添加到singletonFactories中接着进行依赖注入发现自己依赖对象B此时就尝试去get(B)发现B还没有被实例化对B进行实例化然后B在初始化的时候发现自己依赖了对象A于是尝试get(A)尝试一级缓存singletonObjects和二级缓存earlySingletonObjects没找到尝试三级缓存singletonFactories由于A初始化时将自己添加到了singletonFactories所以B可以拿到A对象然后将A从三级缓存中移到二级缓存中B拿到A对象后顺利完成了初始化然后将自己放入到一级缓存singletonObjects中此时返回A中A此时能拿到B的对象顺利完成自己的初始化 由此看出属性注入的循环依赖主要是通过将实例化完成的bean添加到singletonFactories来实现的。而使用构造器依赖注入的bean在实例化的时候会进行依赖注入不会被添加到singletonFactories中。比如A和B都是通过构造器依赖注入A在调用构造器进行实例化的时候发现自己依赖BB没有被实例化就会对B进行实例化此时A未实例化完成不会被添加到singtonFactories。而B依赖于AB会去三级缓存寻找A对象发现不存在于是又会实例化AA实例化了两次从而导致抛异常。 总结1、利用缓存识别已经遍历过的节点 2、利用Java引用先提前设置对象地址后完善对象。 21. Spring启动过程 读取web.xml文件。创建 ServletContext为 ioc 容器提供宿主环境。触发容器初始化事件调用 contextLoaderListener.contextInitialized()方法在这个方法会初始化一个应用上下文WebApplicationContext即 Spring 的 ioc 容器。ioc 容器初始化完成之后会被存储到 ServletContext 中。初始化web.xml中配置的Servlet。如DispatcherServlet用于匹配、处理每个servlet请求。 22. Spring 的单例 Bean 是否有并发安全问题 当多个用户同时请求一个服务时容器会给每一个请求分配一个线程这时多个线程会并发执行该请求对应的业务逻辑如果业务逻辑有对单例状态的修改体现为此单例的成员属性则必须考虑线程安全问题。 无状态bean和有状态bean 有实例变量的bean可以保存数据是非线程安全的。没有实例变量的bean不能保存数据是线程安全的。 在Spring中无状态的Bean适合用单例模式这样可以共享实例提高性能。有状态的Bean在多线程环境下不安全一般用Prototype模式或者使用ThreadLocal解决线程安全问题。 23. Spring Bean如何保证并发安全 Spring的Bean默认都是单例的某些情况下单例是并发不安全的。 以 Controller 举例假如我们在 Controller 中定义了成员变量。当多个请求来临进入的都是同一个单例的 Controller 对象并对此成员变量的值进行修改操作因此会互相影响会有并发安全的问题。 应该怎么解决呢 为了让多个HTTP请求之间不互相影响可以采取以下措施 1、单例变原型 对 web 项目可以 Controller 类上加注解 Scope(prototype) 或 Scope(request)对非 web 项目在 Component 类上添加注解 Scope(prototype) 。 这种方式实现起来非常简单但是很大程度上增大了 Bean 创建实例化销毁的服务器资源开销。 2、尽量避免使用成员变量 在业务允许的条件下可以将成员变量替换为方法中的局部变量。这种方式个人认为是最恰当的。 3、使用并发安全的类 如果非要在单例Bean中使用成员变量可以考虑使用并发安全的容器如 ConcurrentHashMap、ConcurrentHashSet 等等将我们的成员变量包装到这些并发安全的容器中进行管理即可。 4、分布式或微服务的并发安全 如果还要进一步考虑到微服务或分布式服务的影响方式3便不合适了。这种情况下可以借助于可以共享某些信息的分布式缓存中间件如Redis等。这样即可保证同一种服务的不同服务实例都拥有同一份共享信息了。 24. springbean的生命周期 实例化Instantiation当 Spring 容器加载配置文件时会根据配置的 bean 定义实例化相应的 bean 对象。属性注入Property Injection在实例化后Spring 容器会根据配置文件中的依赖关系自动将相应的属性注入给对应的 bean。初始化Initialization在完成属性注入后Spring 容器会调用 bean 的初始化方法如果有定义的话进行一些初始化操作。使用In Use初始化完成后bean 就处于可用状态可以被其他对象引用和使用。销毁Destruction当 Spring 容器关闭时会调用 bean 的销毁方法如果有定义的话进行一些清理工作释放资源。 在 Spring 中可以通过配置文件或注解来定义 bean 的生命周期相关的操作例如在配置文件中可以使用 bean 标签的 init-method 和 destroy-method 属性来指定初始化和销毁方法或者使用 PostConstruct 和 PreDestroy 注解来标注初始化和销毁方法。 25. springboot注解 Conditional是Spring框架中的一个注解可以用于根据条件来决定是否创建某个Bean或者启用某个配置。它的作用是根据条件进行条件化的Bean注册或者配置。 Conditional注解可以用在以下几个地方 在Configuration类中可以用于配置类的条件判断根据条件选择性地加载或者注册某个配置。在Bean方法上可以使用Conditional来决定是否创建某个Bean。当满足条件时该Bean会被创建并注册到ApplicationContext中当条件不满足时该Bean不会被创建。 Conditional注解的使用方式多种多样可以使用Spring提供的一些预定义的条件注解比如ConditionalOnProperty、ConditionalOnClass、ConditionalOnBean等等。此外你还可以实现自定义的条件注解通过实现Condition接口来定义自己的条件逻辑。 通过使用Conditional注解可以在Spring Boot应用中根据不同的条件来实现Bean的动态注册与配置提高了应用的灵活性和自定义能力。 ConditionalOnProperty是Spring框架中的一个条件注解用于根据配置文件中的属性值来决定是否创建某个Bean或者启用某个配置。通过指定属性的名称和值可以根据配置文件中的属性值进行条件判断。 例如我们可以使用ConditionalOnProperty注解来判断是否加载某个Bean Configuration ConditionalOnProperty(name myapp.feature.enabled, havingValue true) public class MyFeatureAutoConfiguration {// Bean definitions } 在上述示例中ConditionalOnProperty注解会根据配置文件中名为myapp.feature.enabled的属性值进行判断。只有当该属性值为true时MyFeatureAutoConfiguration类中的Bean定义才会被加载。 ConditionalOnClass是Spring框架中的另一个条件注解用于根据类的存在与否来决定是否创建某个Bean或者启用某个配置。当指定的类在类路径中存在时才会满足条件。 例如我们可以使用ConditionalOnClass注解来判断是否加载某个Bean Configuration ConditionalOnClass(UserService.class) public class UserServiceAutoConfiguration {// Bean definitions } 在上述示例中只有当类路径中存在UserService类时UserServiceAutoConfiguration类中的Bean定义才会被加载。 ConditionalOnBean是Spring框架中的另一个条件注解用于根据特定的Bean是否存在来决定是否创建其他的Bean或者启用某个配置。当指定的Bean存在于ApplicationContext中时才会满足条件。 例如我们可以使用ConditionalOnBean注解来判断是否加载某个Bean Configuration ConditionalOnBean(UserService.class) public class MyFeatureAutoConfiguration {// Bean definitions } 在上述示例中只有当ApplicationContext中存在UserService类型的Bean时MyFeatureAutoConfiguration类中的Bean定义才会被加载。 通过使用这些条件注解可以根据不同的条件来控制Bean的加载与配置从而实现灵活的应用配置和自定义能力。 ConditionalOnMissingBean ConditionalOnMissingBean是Spring框架中的一个条件注解用于根据是否存在某个Bean来决定是否创建另一个Bean。当指定的Bean在ApplicationContext中不存在时才会满足条件。 例如我们可以使用ConditionalOnMissingBean注解来判断是否创建某个Bean Configuration public class MyBeanConfiguration {BeanConditionalOnMissingBeanpublic MyBean myBean() {// Bean definitionreturn new MyBean();} } 在上述示例中ConditionalOnMissingBean注解用于myBean()方法上。它的作用是判断在ApplicationContext中是否已经存在MyBean类型的Bean如果不存在才会创建并注册该Bean。 这样当ApplicationContext中不存在MyBean类型的Bean时myBean()方法返回的MyBean对象就会被创建并注册到ApplicationContext中但当已经存在MyBean类型的Bean时myBean()方法不会被执行。 通过使用ConditionalOnMissingBean注解可以避免重复创建某个Bean同时也提供了一种在Bean不存在时才创建的方式增加了配置的灵活性。 26. SpringBootApplication注解 除了普通修饰注解类的原信息还有SpringBootConfiguration、EnableAutoConfiguration、ComponentScan 3个注解。 26.1. ComponentScan ComponentScan的功能是自动扫描并加载符合条件的组件(如controller、Component等)最终将这些Bean的定义加载到Ioc容器中。 我们可以通过basePackages等属性来细粒度的定制ComponentScan自动扫描的范围如果不指定则默认Spring框架实现会从声明ComponentScan所在类的package进行扫描。所以通常我们在定义SpringBoot启动类的时候会把它放到root package下这样就能扫描到所有需要定义的类。 26.2. SpringBootConfiguration 这个注解底层是有Configuration注解的 SpringBootConfiguration与Spring中的Configuation的作用基本一致只不过SpringBootConfiguration是springboot的注解而Configuration是spring的注解。 Configuration注解就是把一个类设置为配置类交给Spring容器管理取代了原有的beans.xml配置文件 26.3. EnableAutoConfiguration 自动装配的关键 EnableAutoConfiguration的作用是从classpath中搜寻所有的META-INF/spring.factories配置文件并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射Java Refletion实例化为对应的标注了Configuration的JavaConfig形式的IoC容器配置类然后汇总为一个并加载到IoC容器。 EnableAutoConfiguration 其实也没啥“创意”Spring 框架提供的各种名字为 Enable 开头的 Annotation 定义 比如 EnableScheduling、EnableCaching、EnableMBeanExport 等EnableAutoConfiguration 的理念和“做事方式”其实一脉相承简单概括一下就是借助 Import 的支持收集和注册特定场景相关的 bean 定义 EnableScheduling 是通过 Import 将 Spring 调度框架相关的 bean 定义都加载到 IoC 容器。 EnableMBeanExport 是通过 Import 将 JMX 相关的 bean 定义加载到 IoC 容器。 而 EnableAutoConfiguration 也是借助 Import 的帮助将所有符合自动配置条件的 bean 定义加载到 IoC 容器仅此而已 其中最关键的要属 ImportEnableAutoConfigurationImportSelector.class借助 EnableAutoConfigurationImportSelectorEnableAutoConfiguration 可以帮助 SpringBoot 应用将所有符合条件的 Configuration 配置都加载到当前 SpringBoot 创建并使用的 IoC 容器 26.3.1. AutoConfigurationPackage 可以自动配置扫描到的包 26.3.1.1. Import(AutoConfigurationPackages.Registrar.class) Import用于导入其他配置类或者组件类。它可以被用来在一个配置类中引入其他配置类以便将它们的配置信息合并到当前的配置中。它的作用,就是注册启动类所在的包和其子包下的所有组件 用于注册Bean定义到Spring容器的 中。在这里registerBeanDefinitions方法通过PackageImports类获取到注解元数据中的包名并将这些包名作为参数调用register方法进行注册 PackageImports register 26.4. Import(AutoConfigurationImportSelector.class) getCandidateConfigurations: 调用 getCandidateConfigurations 方法获取候选的配置类列表。 protected ListString getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {ListString configurations new ArrayList(SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()));ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()).forEach(configurations::add);Assert.notEmpty(configurations,No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.);return configurations; } 该方法的作用是获取候选的自动配置类列表 SpringFactoriesLoader.loadFactoryNames 方法会加载外部配置文件,通过加载META-INF/spring.factories ImportCandidates.load会加载 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中的配置类信息以及通过ImportCandidates加载的自动配置类构建一个配置类的列表。这些候选的配置类将被后续的自动配置过程使用。 ImportCandidates.load ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()).forEach(configurations::add): 使用ImportCandidates工具类从META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中加载自动配置类并将它们添加到配置类列表中。AutoConfiguration.class是一个标记接口用于指示需要加载的自动配置类。 String location String.format(LOCATION, annotation.getName()): 根据指定注解的名称构建位置字符串。LOCATION是一个字符串常量用于定义位置的格式。 load方法的作用是根据指定的注解通过查找类路径中匹配的URL资源读取候选自动配置类并将它们存储在ImportCandidates对象中返回。ImportCandidates是一个简单的封装类用于存储候选自动配置类的列表。 loadFactoryNames SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()): 使用Spring框架提供的SpringFactoriesLoader从META-INF/spring.factories文件中加载自动配置类的工厂名称并将其存储在一个新的ArrayList中。getSpringFactoriesLoaderFactoryClass()是一个方法用于获取SpringFactoriesLoader的工厂类。 private static MapString, ListString loadSpringFactories(ClassLoader classLoader) {MapString, ListString result cache.get(classLoader);if (result ! null) {return result;}result new HashMap();try {EnumerationURL urls classLoader.getResources(FACTORIES_RESOURCE_LOCATION);while (urls.hasMoreElements()) {URL url urls.nextElement();UrlResource resource new UrlResource(url);Properties properties PropertiesLoaderUtils.loadProperties(resource);for (Map.Entry?, ? entry : properties.entrySet()) {String factoryTypeName ((String) entry.getKey()).trim();String[] factoryImplementationNames StringUtils.commaDelimitedListToStringArray((String) entry.getValue());for (String factoryImplementationName : factoryImplementationNames) {result.computeIfAbsent(factoryTypeName, key - new ArrayList()).add(factoryImplementationName.trim());}}}// Replace all lists with unmodifiable lists containing unique elementsresult.replaceAll((factoryType, implementations) - implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)));cache.put(classLoader, result);}catch (IOException ex) {throw new IllegalArgumentException(Unable to load factories from location [ FACTORIES_RESOURCE_LOCATION ], ex);}return result; }
http://www.dnsts.com.cn/news/31680.html

相关文章:

  • 地方网站类型在线crm视频
  • 网站前端跟后端怎么做怎么查名字有没有被注册商标
  • 中山网站建设公司哪家好phpcms 做购物网站
  • 怎样把自己的网站进行推广wordpress评论者名字
  • 苏州营销型网站开发公司外贸seo优化公司
  • hao123网站难做吗国内有wix做的好的网站
  • 香橼做空机构网站架设网站的目的
  • 中山做网站的公司胶州建设局网站
  • 深圳外贸网站推广六盘水建设网站
  • 电商网站建设案例怎么建设网站页面
  • lamp网站开发黄金组合制作网站后台
  • 网站建设开始学什么美食网站策划书范文
  • 毕业设计做旅游网站合肥网站建设模板
  • 帝国 cms 网站关键字wordpress使用缩略图
  • 一个网站需要多少空间网站建设首选定制开发
  • 专业合肥网站建设中山网站快照优化公司
  • 网站栏目建设评活动企业建站平台哪个好
  • 网站关键词的使用成都柚米科技公众号开发
  • 南京房产网站建设珠宝怎么做网站
  • 国家住房城乡建设部网站我是做废品回收,最近有个变宝网主动联系我说是再生资源网站的,可信吗?
  • 仿站定制模板建站seo平台优化
  • 网站建设 个人潍坊网站建设尚荣
  • 德州定制网站建设公司柳州 网站开发
  • 买好域名之后怎么做网站九江浔阳网站建设
  • 网站开发容易找工作吗网站建设竞标ppt
  • 如何建设盈利网站正规优化公司哪家好
  • 网站二维码弹窗上海建立公司网站
  • 手机做图纸app下载网站想做一个电影网站该怎么做
  • 民族服装的网站建设南通网站制作怎样
  • 做网站运营工作流程网站建设的售后服务怎么写