Spring By example -- core

Spring IoC 容器详解与使用
本文深入探讨 Spring IoC 容器的实现、初始化过程、依赖注入方式及配置选项,包括 BeanFactory 和 ApplicationContext 的区别,XML 配置方式,注入方法如接口注入、setter 注入和构造器注入,以及如何通过 Spring 的命名空间进行配置。

Spring IOC 容器的两种实现  BeanFactory 和ApplicationContext

DefaultListableBeanFactory作为一个功能完备的默认的IOC容器

 

ApplicationContext 除了基本的功能外,还支持不同的信息源,访问资源,支持应用事件,提供附加服务;比基本的BeanFactory提供了更高级的形态

 

IOC容器的初始化过程

1. BeanDefinitioin的Resource定位

    对于不同的ApplicationContext,会对应不同的Rsource,例如ClassPathResource,ServletContextResource等

2. BeanDeifinition的载入和解析

3. BeanDefinition在容器中的注册

 

IOC容器的依赖注入

触发于getBean,具体过程可以参考AbstractBeanFactory的doGetBean

1.从缓存中取得,如果已创建,则返回否则转2

2. 在双亲BeanFactory中寻找,如果找不到,则递归调用寻找,如果找到返回,否则转3

3. 如果有依赖Bean则递归查找,一直找到没有任何依赖Bean,

    BeanWrapper完成Bean的属性注入

 

Spring comes with several XML namespaces through which you can configure the Spring

container

aop  Provides elements for declaring aspects and for automatically proxying @AspectJannotated classes as Spring aspects.

beans The core primitive Spring namespace, enabling declaration of beans and how they

should be wired.

context Comes with elements for configuring the Spring application context, including the abil-

ity to autodetect and autowire beans and injection of objects not directly managed by

Spring.

jee Offers integration with Java EE APIs such as JNDI and EJB.

jms Provides configuration elements for declaring message-driven POJOs.

lang Enables declaration of beans that are implemented as Groovy, JRuby, or BeanShell

scripts.

mvc Enables Spring MVC capabilities such as annotation-oriented controllers, view control-

lers, and interceptors.

oxm Supports configuration of Spring’s object-to-XML mapping facilities.

tx Provides for declarative transaction configuration.

util A miscellaneous selection of utility elements. Includes the ability to declare collec-

tions as beans and support for property placeholder elements.

 

Spring注入方式

接口注入,setter注入,构造器注入

Injecting simple values

<bean id="kenny"
class="com.springinaction.springidol.Instrumentalist">
<propertyname="song"value="JingleBells"/>
</bean>

 Referencing other beans

<bean id="saxophone"
class="com.springinaction.springidol.Saxophone"/>

<bean id="kenny2"
class="com.springinaction.springidol.Instrumentalist">
<propertyname="song"value="JingleBells"/>
<propertyname="instrument"ref="saxophone"/>
</bean>

 INJECTING INNER BEANS

<bean id="kenny"
class="com.springinaction.springidol.Instrumentalist">
<propertyname="song"value="JingleBells"/>
<propertyname="instrument">
<beanclass="org.springinaction.springidol.Saxophone"/>
</property>
</bean>


--------------------------------

<bean id="duke"
class="com.springinaction.springidol.PoeticJuggler">
<constructor-argvalue="15"/>
<constructor-arg>
<beanclass="com.springinaction.springidol.Sonnet29"/>
</constructor-arg>
</bean>

 

Wiring properties with Spring’s p namespace

 

 

<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

 

<bean id="kenny"class="com.springinaction.springidol.Instrumentalist"
p:song="JingleBells"
p:instrument-ref="saxophone"/>

 

Wiring collections

 

<list> Wiring a list of values, allowing duplicates

<set> Wiring a set of values, ensuring no duplicates

<map> Wiring a collection of name-value pairs where name and value

can be of any type

<props> Wiring a collection of name-value pairs where the name and

value are both Strings

 

<bean id="hank"
class="com.springinaction.springidol.OneManBand">
<propertyname="instruments">
<list>
<refbean="guitar"/>
<refbean="cymbal"/>
<refbean="harmonica"/>
</list>
</property>
</bean>

 

<bean id="hank"
class="com.springinaction.springidol.OneManBand">
<propertyname="instruments">
<set>
<ref bean="guitar"/>
<ref bean="cymbal"/>
<ref bean="harmonica"/>
<ref bean="harmonica"/>
</set>
</property>
</bean>

 

 

 

<bean id="hank"class="com.springinaction.springidol.OneManBand">
<propertyname="instruments">
<map>
<entry key="GUITAR" value-ref="guitar"/>
<entry key="CYMBAL" value-ref="cymbal"/>
<entry key="HARMONICA" value-ref="harmonica"/>
</map>
</property>
</bean>

 map wiring property

key Specifies the key of the map entry as a String

key-ref Specifies the key of the map entry as a reference to a bean in the Spring context

value Specifies the value of the map entry as a String

value-ref Specifies the value of the map entry as a reference to a bean in the Spring context

 

private Propertiesinstruments;
public voidsetInstruments(Propertiesinstruments){
this.instruments=instruments;
}

 

<bean id="hank"class="com.springinaction.springidol.OneManBand">
<propertyname="instruments">
<props>
<propkey="GUITAR">STRUMSTRUMSTRUM</prop>
<propkey="CYMBAL">CRASHCRASHCRASH</prop>
<propkey="HARMONICA">HUMHUMHUM</prop>
</props>
</property>
</bean>

 

 

bean scopes

singleton Scopes the bean definition to a single instance per Spring container (default).

prototype Allows a bean to be instantiated any number of times (once per use).

request Scopes a bean definition to an HTTP request. Only valid when used with a

web-capable Spring context (such as with Spring MVC).

session Scopes a bean definition to an HTTP session. Only valid when used with a

web-capable Spring context (such as with Spring MVC).

global-session Scopes a bean definition to a global HTTP session. Only valid when used in a portlet context.

 

Initializing and destroying beans

第一种 定义 init-method   destroy-method

<bean id="auditorium"
class="com.springinaction.springidol.Auditorium"
init-method="turnOnLights"
destroy-method="turnOffLights"/>

 第二种  实现InitializingBean和DisposableBean

            如果用第二种方式,你的代码是和sping耦合在一起的,建议不使用

第三种 default-init-method default-destroy-method  

         这种情况适合于有多个bean同时定义了相同的初始化和销毁方法

D:\Java安装\bin\java.exe -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-Dmanagement.endpoints.jmx.exposure.include=*" "-javaagent:D:\Idea\IntelliJ IDEA 2024.1.2\lib\idea_rt.jar=60039:D:\Idea\IntelliJ IDEA 2024.1.2\bin" -Dfile.encoding=UTF-8 -classpath D:\SpringBoot开发\作业\exam\target\classes;C:\Users\33635\.m2\repository\org\springframework\boot\spring-boot-starter-security\3.5.3\spring-boot-starter-security-3.5.3.jar;C:\Users\33635\.m2\repository\org\springframework\boot\spring-boot-starter\3.5.3\spring-boot-starter-3.5.3.jar;C:\Users\33635\.m2\repository\org\springframework\boot\spring-boot\3.5.3\spring-boot-3.5.3.jar;C:\Users\33635\.m2\repository\org\springframework\boot\spring-boot-starter-logging\3.5.3\spring-boot-starter-logging-3.5.3.jar;C:\Users\33635\.m2\repository\ch\qos\logback\logback-classic\1.5.18\logback-classic-1.5.18.jar;C:\Users\33635\.m2\repository\ch\qos\logback\logback-core\1.5.18\logback-core-1.5.18.jar;C:\Users\33635\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.24.3\log4j-to-slf4j-2.24.3.jar;C:\Users\33635\.m2\repository\org\apache\logging\log4j\log4j-api\2.24.3\log4j-api-2.24.3.jar;C:\Users\33635\.m2\repository\org\slf4j\jul-to-slf4j\2.0.17\jul-to-slf4j-2.0.17.jar;C:\Users\33635\.m2\repository\org\yaml\snakeyaml\2.4\snakeyaml-2.4.jar;C:\Users\33635\.m2\repository\org\springframework\spring-aop\6.2.8\spring-aop-6.2.8.jar;C:\Users\33635\.m2\repository\org\springframework\security\spring-security-config\6.5.1\spring-security-config-6.5.1.jar;C:\Users\33635\.m2\repository\org\springframework\security\spring-security-web\6.5.1\spring-security-web-6.5.1.jar;C:\Users\33635\.m2\repository\org\springframework\spring-expression\6.2.8\spring-expression-6.2.8.jar;C:\Users\33635\.m2\repository\org\springframework\boot\spring-boot-starter-web\3.5.3\spring-boot-starter-web-3.5.3.jar;C:\Users\33635\.m2\repository\org\springframework\boot\spring-boot-starter-json\3.5.3\spring-boot-starter-json-3.5.3.jar;C:\Users\33635\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.19.1\jackson-databind-2.19.1.jar;C:\Users\33635\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.19.1\jackson-annotations-2.19.1.jar;C:\Users\33635\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.19.1\jackson-core-2.19.1.jar;C:\Users\33635\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.19.1\jackson-datatype-jdk8-2.19.1.jar;C:\Users\33635\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.19.1\jackson-datatype-jsr310-2.19.1.jar;C:\Users\33635\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.19.1\jackson-module-parameter-names-2.19.1.jar;C:\Users\33635\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\3.5.3\spring-boot-starter-tomcat-3.5.3.jar;C:\Users\33635\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\10.1.42\tomcat-embed-core-10.1.42.jar;C:\Users\33635\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\10.1.42\tomcat-embed-el-10.1.42.jar;C:\Users\33635\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\10.1.42\tomcat-embed-websocket-10.1.42.jar;C:\Users\33635\.m2\repository\org\springframework\spring-web\6.2.8\spring-web-6.2.8.jar;C:\Users\33635\.m2\repository\io\micrometer\micrometer-observation\1.15.1\micrometer-observation-1.15.1.jar;C:\Users\33635\.m2\repository\io\micrometer\micrometer-commons\1.15.1\micrometer-commons-1.15.1.jar;C:\Users\33635\.m2\repository\org\springframework\spring-webmvc\6.2.8\spring-webmvc-6.2.8.jar;C:\Users\33635\.m2\repository\org\springframework\boot\spring-boot-starter-thymeleaf\3.5.3\spring-boot-starter-thymeleaf-3.5.3.jar;C:\Users\33635\.m2\repository\org\thymeleaf\thymeleaf-spring6\3.1.3.RELEASE\thymeleaf-spring6-3.1.3.RELEASE.jar;C:\Users\33635\.m2\repository\org\thymeleaf\thymeleaf\3.1.3.RELEASE\thymeleaf-3.1.3.RELEASE.jar;C:\Users\33635\.m2\repository\org\attoparser\attoparser\2.0.7.RELEASE\attoparser-2.0.7.RELEASE.jar;C:\Users\33635\.m2\repository\org\unbescape\unbescape\1.1.6.RELEASE\unbescape-1.1.6.RELEASE.jar;C:\Users\33635\.m2\repository\org\thymeleaf\extras\thymeleaf-extras-springsecurity6\3.1.3.RELEASE\thymeleaf-extras-springsecurity6-3.1.3.RELEASE.jar;C:\Users\33635\.m2\repository\org\slf4j\slf4j-api\2.0.17\slf4j-api-2.0.17.jar;C:\Users\33635\.m2\repository\com\baomidou\mybatis-plus-boot-starter\3.5.7\mybatis-plus-boot-starter-3.5.7.jar;C:\Users\33635\.m2\repository\com\baomidou\mybatis-plus\3.5.7\mybatis-plus-3.5.7.jar;C:\Users\33635\.m2\repository\com\baomidou\mybatis-plus-core\3.5.7\mybatis-plus-core-3.5.7.jar;C:\Users\33635\.m2\repository\com\baomidou\mybatis-plus-annotation\3.5.7\mybatis-plus-annotation-3.5.7.jar;C:\Users\33635\.m2\repository\com\baomidou\mybatis-plus-extension\3.5.7\mybatis-plus-extension-3.5.7.jar;C:\Users\33635\.m2\repository\org\mybatis\mybatis\3.5.16\mybatis-3.5.16.jar;C:\Users\33635\.m2\repository\com\github\jsqlparser\jsqlparser\4.9\jsqlparser-4.9.jar;C:\Users\33635\.m2\repository\org\mybatis\mybatis-spring\2.1.2\mybatis-spring-2.1.2.jar;C:\Users\33635\.m2\repository\com\baomidou\mybatis-plus-spring-boot-autoconfigure\3.5.7\mybatis-plus-spring-boot-autoconfigure-3.5.7.jar;C:\Users\33635\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\3.5.3\spring-boot-autoconfigure-3.5.3.jar;C:\Users\33635\.m2\repository\org\springframework\boot\spring-boot-starter-jdbc\3.5.3\spring-boot-starter-jdbc-3.5.3.jar;C:\Users\33635\.m2\repository\com\zaxxer\HikariCP\6.3.0\HikariCP-6.3.0.jar;C:\Users\33635\.m2\repository\org\springframework\spring-jdbc\6.2.8\spring-jdbc-6.2.8.jar;C:\Users\33635\.m2\repository\com\mysql\mysql-connector-j\9.2.0\mysql-connector-j-9.2.0.jar;C:\Users\33635\.m2\repository\org\projectlombok\lombok\1.18.38\lombok-1.18.38.jar;C:\Users\33635\.m2\repository\org\springframework\spring-core\6.2.8\spring-core-6.2.8.jar;C:\Users\33635\.m2\repository\org\springframework\spring-jcl\6.2.8\spring-jcl-6.2.8.jar;C:\Users\33635\.m2\repository\org\springframework\security\spring-security-core\6.5.1\spring-security-core-6.5.1.jar;C:\Users\33635\.m2\repository\org\springframework\security\spring-security-crypto\6.5.1\spring-security-crypto-6.5.1.jar;C:\Users\33635\.m2\repository\org\springframework\data\spring-data-jpa\3.4.4\spring-data-jpa-3.4.4.jar;C:\Users\33635\.m2\repository\org\springframework\data\spring-data-commons\3.5.1\spring-data-commons-3.5.1.jar;C:\Users\33635\.m2\repository\org\springframework\spring-orm\6.2.8\spring-orm-6.2.8.jar;C:\Users\33635\.m2\repository\org\springframework\spring-context\6.2.8\spring-context-6.2.8.jar;C:\Users\33635\.m2\repository\org\springframework\spring-tx\6.2.8\spring-tx-6.2.8.jar;C:\Users\33635\.m2\repository\org\springframework\spring-beans\6.2.8\spring-beans-6.2.8.jar;C:\Users\33635\.m2\repository\org\antlr\antlr4-runtime\4.13.0\antlr4-runtime-4.13.0.jar;C:\Users\33635\.m2\repository\jakarta\annotation\jakarta.annotation-api\2.1.1\jakarta.annotation-api-2.1.1.jar com.example.exam.ExamApplication . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.5.3) 2025-06-22T14:38:31.044+08:00 INFO 10080 --- [exam] [ main] com.example.exam.ExamApplication : Starting ExamApplication using Java 17.0.14 with PID 10080 (D:\SpringBoot开发\作业\exam\target\classes started by 33635 in D:\SpringBoot开发\作业\exam) 2025-06-22T14:38:31.046+08:00 INFO 10080 --- [exam] [ main] com.example.exam.ExamApplication : No active profile set, falling back to 1 default profile: "default" 2025-06-22T14:38:31.467+08:00 INFO 10080 --- [exam] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. 2025-06-22T14:38:31.506+08:00 INFO 10080 --- [exam] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 33 ms. Found 1 JPA repository interface. 2025-06-22T14:38:31.509+08:00 WARN 10080 --- [exam] [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfiguration.stringHttpMessageConverter 2025-06-22T14:38:31.515+08:00 INFO 10080 --- [exam] [ main] .s.b.a.l.ConditionEvaluationReportLogger : Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. 2025-06-22T14:38:31.528+08:00 ERROR 10080 --- [exam] [ main] o.s.boot.SpringApplication : Application run failed java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfiguration.stringHttpMessageConverter at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-3.5.3.jar:3.5.3] at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:99) ~[spring-context-6.2.8.jar:6.2.8] at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:186) ~[spring-context-6.2.8.jar:6.2.8] at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:147) ~[spring-context-6.2.8.jar:6.2.8] at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:123) ~[spring-context-6.2.8.jar:6.2.8] at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:430) ~[spring-context-6.2.8.jar:6.2.8] at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:290) ~[spring-context-6.2.8.jar:6.2.8] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349) ~[spring-context-6.2.8.jar:6.2.8] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118) ~[spring-context-6.2.8.jar:6.2.8] at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:791) ~[spring-context-6.2.8.jar:6.2.8] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:609) ~[spring-context-6.2.8.jar:6.2.8] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.3.jar:3.5.3] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.3.jar:3.5.3] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.3.jar:3.5.3] at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.3.jar:3.5.3] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.3.jar:3.5.3] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.3.jar:3.5.3] at com.example.exam.ExamApplication.main(ExamApplication.java:12) ~[classes/:na] Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.orm.jpa.SharedEntityManagerCreator] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b] at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:483) ~[spring-core-6.2.8.jar:6.2.8] at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:360) ~[spring-core-6.2.8.jar:6.2.8] at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:417) ~[spring-core-6.2.8.jar:6.2.8] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$1(AbstractAutowireCapableBeanFactory.java:757) ~[spring-beans-6.2.8.jar:6.2.8] at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[na:na] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:756) ~[spring-beans-6.2.8.jar:6.2.8] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:689) ~[spring-beans-6.2.8.jar:6.2.8] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:660) ~[spring-beans-6.2.8.jar:6.2.8] at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1716) ~[spring-beans-6.2.8.jar:6.2.8] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:639) ~[spring-beans-6.2.8.jar:6.2.8] at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:611) ~[spring-beans-6.2.8.jar:6.2.8] at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:596) ~[spring-beans-6.2.8.jar:6.2.8] at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanDefinitionsForType(OnBeanCondition.java:322) ~[spring-boot-autoconfigure-3.5.3.jar:3.5.3] at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanDefinitionsForType(OnBeanCondition.java:314) ~[spring-boot-autoconfigure-3.5.3.jar:3.5.3] at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:214) ~[spring-boot-autoconfigure-3.5.3.jar:3.5.3] at org.springframework.boot.autoconfigure.condition.OnBeanCondition.evaluateConditionalOnMissingBean(OnBeanCondition.java:197) ~[spring-boot-autoconfigure-3.5.3.jar:3.5.3] at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:144) ~[spring-boot-autoconfigure-3.5.3.jar:3.5.3] at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-3.5.3.jar:3.5.3] ... 17 common frames omitted Caused by: java.lang.NoClassDefFoundError: jakarta/persistence/EntityManagerFactory at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na] at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3402) ~[na:na] at java.base/java.lang.Class.getDeclaredMethods(Class.java:2504) ~[na:na] at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:465) ~[spring-core-6.2.8.jar:6.2.8] ... 34 common frames omitted Caused by: java.lang.ClassNotFoundException: jakarta.persistence.EntityManagerFactory at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[na:na] ... 38 common frames omitted 进程已结束,退出代码为 1
06-23
<think>我们遇到了一个启动错误,错误信息是:`java.lang.IllegalStateException:Errorprocessingconditiononorg.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfiguration.stringHttpMessageConverter`,根本原因是`java.lang.ClassNotFoundException:jakarta.persistence.EntityManagerFactory`。这个错误表明在类路径中缺少`jakarta.persistence.EntityManagerFactory`类,这个类属于JakartaPersistenceAPI(JPA)的一部分。在SpringBoot项目中,我们通常通过引入`spring-boot-starter-data-jpa`来获得JPA的支持。观察你的依赖,我发现你的pom.xml中并没有直接引入`spring-boot-starter-data-jpa`,但是有`mybatis-plus-boot-starter`和`spring-data-jpa`。注意,`spring-data-jpa`并不包含完整的JPA实现(如Hibernate),它只是SpringDataJPA模块。同时,MyBatisPlus是一个持久层框架,它并不提供JPA的实现。错误发生在处理`HttpMessageConvertersAutoConfiguration`的条件时,但是根本原因是缺少`EntityManagerFactory`类,这通常是因为JPA相关的依赖没有正确引入。解决方案:1.如果你打算使用JPA(例如Hibernate),那么你需要引入`spring-boot-starter-data-jpa`。2.如果你不打算使用JPA,而是使用MyBatisPlus,那么你可能需要排除掉一些自动配置,或者检查是否有地方错误地引入了JPA的依赖或配置。但是,根据堆栈信息,问题出现在`org.springframework.orm.jpa.SharedEntityManagerCreator`,这个类是SpringORMJPA模块的一部分。这意味着你的项目中有一些代码或配置试图使用JPA,但是缺少必要的依赖。由于你同时引入了`spring-data-jpa`(版本3.4.4)和`mybatis-plus-boot-starter`,这可能会导致冲突。因为MyBatis和JPA是两种不同的持久化方案,通常我们不会同时使用它们。因此,你有两个选择:选择一:移除JPA相关依赖,只使用MyBatisPlus。选择二:同时使用MyBatis和JPA(但通常不推荐同时使用两个持久化框架)。我猜测你实际上是想使用MyBatisPlus,那么你应该移除`spring-data-jpa`依赖。但是,在错误堆栈中,我们也看到了`org.springframework.orm.jpa`包,这个包是由`spring-orm`提供的。而`spring-orm`是Spring框架的一部分,用于支持ORM(包括JPA、Hibernate等)。在引入`spring-data-jpa`时,它会传递依赖`spring-orm`。因此,我建议:1.移除`spring-data-jpa`依赖,因为你要使用MyBatisPlus。2.确保没有其他代码依赖JPA(例如,没有使用`EntityManager`或`JpaRepository`)。修改pom.xml,移除`spring-data-jpa`依赖:如果你当前的pom.xml中有:```xml<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-jpa</artifactId><version>3.4.4</version></dependency>```请删除它。另外,如果你使用的是SpringBoot,那么通常不需要直接指定`spring-data-jpa`的版本,因为SpringBoot管理版本。但既然你要移除它,就不需要了。但是,检查你的依赖列表,我注意到你的依赖中已经包含了`spring-data-jpa`(版本3.4.4)和`spring-data-commons`(版本3.5.1)。版本不一致也可能导致问题。所以,请确保移除所有与JPA相关的依赖。如果移除后仍然有问题,可能是因为其他依赖传递引入了JPA相关的包。你可以使用`mvndependency:tree`查看依赖树,并排除掉不需要的依赖。另外,检查你的代码中是否有使用JPA的注解(如`@Entity`,`@Table`等)?如果你使用MyBatisPlus,通常你会使用MyBatis的注解(如`@TableName`)或XML映射文件。如果你确实需要使用JPA注解(比如为了实体类),那么你需要引入JPAAPI依赖(但不一定需要完整的JPA实现)。但是,在SpringBoot中,为了使用JPA注解,通常还是需要引入`spring-boot-starter-data-jpa`,因为它会提供必要的依赖。不过,MyBatisPlus也可以使用JPA注解,但是需要额外引入JPAAPI。你可以单独引入JPAAPI依赖(而不引入实现)。例如:```xml<dependency><groupId>jakarta.persistence</groupId><artifactId>jakarta.persistence-api</artifactId><version>3.1.0</version></dependency>```但是,根据错误信息,缺少的类`jakarta.persistence.EntityManagerFactory`正是这个API中的类。所以,如果你在实体类中使用了JPA注解,那么你需要这个依赖。总结:根据错误信息,项目启动时因为缺少`jakarta.persistence.EntityManagerFactory`类而失败。这个类属于JakartaPersistenceAPI(JPA)。因此,有两种解决方案:方案一(推荐):如果你不使用JPA,那么移除所有使用JPA的代码和依赖。-移除`spring-data-jpa`依赖。-确保代码中没有使用JPA相关的内容(比如`EntityManager`、`JpaRepository`等)。方案二:如果你确实需要JPAAPI(比如在实体类上使用JPA注解),则引入JPAAPI依赖:```xml<dependency><groupId>jakarta.persistence</groupId><artifactId>jakarta.persistence-api</artifactId><version>3.1.0</version></dependency>```但是,注意:如果你引入了JPAAPI,但是不提供实现(如Hibernate),那么当你尝试使用JPA操作数据库时,会遇到`NoClassDefFoundError`或`NoSuchBeanDefinitionException`。所以,如果只是使用注解,不涉及JPA操作,那么只引入API即可。由于你的项目使用了MyBatisPlus,我假设你不需要JPA的操作,但可能实体类上用了JPA注解。在这种情况下,引入JPAAPI即可。因此,我建议在pom.xml中添加:```xml<dependency><groupId>jakarta.persistence</groupId><artifactId>jakarta.persistence-api</artifactId><version>3.1.0</version></dependency>```然后重新启动项目。如果问题依然存在,请检查依赖树,排除冲突的依赖。另外,注意错误堆栈中提到的`SharedEntityManagerCreator`,它是SpringORM的一部分,用于JPA。如果移除了JPA依赖,这个类不应该被加载。所以,如果添加了JPAAPI后问题仍然存在,可能是Spring自动配置试图创建JPA相关的Bean,而你没有提供必要的配置(如数据源配置给JPA使用)。此时,你需要排除JPA的自动配置。在SpringBoot主类上排除JPA自动配置:```java@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class})```但是,由于你使用了MyBatisPlus,它需要数据源和事务管理器,所以不能排除`DataSourceAutoConfiguration`和`DataSourceTransactionManagerAutoConfiguration`。但是可以排除`HibernateJpaAutoConfiguration`。不过,在SpringBoot3中,自动配置类可能有变化。根据你的情况,如果添加了JPAAPI依赖后仍然报错,可以尝试排除JPA相关的自动配置:```java@SpringBootApplication(exclude={DataSourceJpaConfiguration.class,JpaBaseConfiguration.class})```但是,更简单的方式是,在`application.properties`中禁用JPA:```propertiesspring.data.jpa.repositories.enabled=falsespring.jpa.enabled=false```但这样可能还不够,因为自动配置可能会因为类路径存在某些类而触发。所以,最好的方式是在启动类上排除特定的自动配置类。然而,由于错误发生在`HttpMessageConvertersAutoConfiguration`的条件处理过程中,这可能是由于条件评估时类路径的混乱导致的。因此,添加JPAAPI依赖应该是最直接的解决方案。步骤总结:1.在pom.xml中添加`jakarta.persistence-api`依赖。2.如果启动成功,则问题解决。3.如果启动失败,尝试排除JPA自动配置。下面给出pom.xml中添加依赖的示例:```xml<dependencies><!--其他依赖--><dependency><groupId>jakarta.persistence</groupId><artifactId>jakarta.persistence-api</artifactId><version>3.1.0</version></dependency></dependencies>```然后重新启动应用。如果添加后仍然出现同样的错误,请检查依赖树,看是否有其他依赖引入了旧版本的JPAAPI(如javax.persistence)导致冲突。在SpringBoot3中,应该使用JakartaPersistence3.0+。另外,注意你的依赖中有一个`org.springframework.data:spring-data-jpa:3.4.4`,这个依赖会传递引入`jakarta.persistence:jakarta.persistence-api`,但是版本可能是2.x。因此,显式引入3.1.0版本可以覆盖传递依赖的版本。最后,如果问题依旧,请尝试使用`mvndependency:tree`查看依赖关系,并排除冲突的依赖。由于时间关系,这里先提供添加依赖的解决方案。如果后续还有问题,可以根据错误日志再调整。如果以上方法都不能解决问题,请提供完整的pom.xml文件以便进一步分析。现在,假设我们通过添加JPAAPI依赖来解决,下面是修改后的pom.xml片段:注意:版本3.1.0是当前最新的稳定版本,与SpringBoot3兼容。请尝试添加这个依赖并重新启动应用。如果问题解决,那么就可以继续开发了。如果还有其他问题,请根据新的错误日志再进行调整。</think>从错误日志来看,你的 Spring Boot 应用启动失败,主要原因是缺少 Jakarta Persistence API 的依赖。以下是详细分析和解决方案: ### 问题分析 1. **核心错误**: ``` Caused by: java.lang.ClassNotFoundException: jakarta.persistence.EntityManagerFactory ``` 这表明你的项目中缺少 Jakarta Persistence API (JPA) 依赖。 2. **错误链**: - 应用尝试加载 `org.springframework.orm.jpa.SharedEntityManagerCreator` - 这个类依赖于 `jakarta.persistence.EntityManagerFactory` - 由于缺少 JPA 依赖,导致类加载失败 3. **依赖检查**: 从你的依赖列表中可以看到: - 有 `spring-data-jpa` (Spring Data JPA) - 但没有 JPA 实现(如 Hibernate)或 API 依赖 ### 解决方案 #### 1. 添加 Jakarta Persistence API 依赖 在 `pom.xml` 中添加以下依赖: ```xml <dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.1.0</version> </dependency> ``` #### 2. 添加 JPA 实现(推荐) 更完整的解决方案是添加 Hibernate 作为 JPA 实现(Spring Boot Starter Data JPA 会自动包含它): ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` #### 3. 完整修复后的 `pom.xml` 示例 ```xml <dependencies> <!-- 已有依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- 新增的 JPA 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- 测试依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> ``` ### 为什么需要这些依赖? 1. **Jakarta Persistence API**: - 提供 JPA 规范接口 - 包含 `EntityManagerFactory`、`EntityManager` 等核心接口 - Spring ORM 需要这些接口来管理 JPA 实体 2. **Hibernate**: - 最流行的 JPA 实现 - 通过 `spring-boot-starter-data-jpa` 自动引入 - 提供实际的对象关系映射(ORM)功能 ### 验证解决方案 添加依赖后,重新运行应用。你应该会看到类似以下启动日志: ``` 2025-06-22T15:00:00.000+08:00 INFO 12345 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) 2025-06-22T15:00:00.002+08:00 INFO 12345 --- [main] com.example.exam.ExamApplication : Started ExamApplication in 5.456 seconds (process running for 6.789) ``` ### 其他可能的问题 1. **依赖冲突**: - 如果你同时使用 MyBatis 和 JPA,确保它们配置正确 - 在 `application.properties` 中明确指定 ORM 提供者: ```properties spring.main.web-application-type=servlet spring.jpa.provider=hibernate ``` 2. **版本兼容性**: - 确保所有依赖版本兼容 - Spring Boot 3.x 需要 Jakarta EE 9+ 依赖(不再支持 javax.persistence) 3. **实体类扫描**: - 确保实体类有 `@Entity` 注解 - 在主应用类添加实体扫描路径: ```java @SpringBootApplication @EntityScan("com.example.exam.entity") public class ExamApplication { public static void main(String[] args) { SpringApplication.run(ExamApplication.class, args); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值