尝试使用构造函数参数在spring实例化的bean中创建Spring应用程序上下文时,我遇到了一个问题.
我已经实现了ApplicationContextAware接口,但它在创建实例后填充了上下文(显而易见).
但是,如果你需要从构造函数中获取bean,并且我在谈论在运行时定义的可变数量的对象,那么正确的方法是什么?
我知道我的问题是一个普遍的问题,但是我在这里检查了很多问题,检查了Spring文档,但我真的不知道我在做什么错。我的问题:我有一个使用JPA的Spring WebFlow项目(实现:OpenJPA + MySQL数据库)。我使用Spring ORM将EntityManager(通过@PersistenceContext注释)注入到我的简单RegisterDAO中。我已经配置了GlassFishs(正在使用的)连接池以使用MySQL,并且一切正常-我可以使用我的数据库,但是当我保留某些东西时-没有任何反应(数据未保留到数据库)。我知道问题出在我使用的事务上下文中。我阅读了Spring Transaction Management的文档,并按照本文档中的配置步骤进行操作。这是我的applicationContext.xml:
<?xml version="1.0" encoding="windows-1250"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<jee:jndi-lookup id="entityManagerFactory" jndi-name="myPersistenceUnit"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="registerDaoImpl" class="umk.dumont.db.dao.RegisterDAO" />
<bean id="registerModel" class="umk.dumont.models.RegisterFormModel">
<property name="registerDAO" ref="registerDaoImpl" />
</bean>
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="registerModelOperation" expression="execution(* umk.dumont.models.RegisterFormModel.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="registerModelOperation"/>
</aop:config>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
</beans>
Run Code Online (Sandbox Code Playgroud)
如您所见,我正在将RegisterDAO注入我的RegisterFormModel中,其中包含我的业务逻辑,用于验证注册表单数据并最终将用户添加到数据库中。验证工作正常,当我尝试添加新用户时出现问题。这是代码:
package umk.dumont.models;
...
public class RegisterFormModel implements Serializable {
private String login;
private …Run Code Online (Sandbox Code Playgroud) 我正在练习Spring,当我尝试实例化上下文时,我得到了一个java.lang.ExceptionInInitializerError异常.下面显示了Exception,我的代码跟随它.我从以前简化了我的实验.
例外
Oct 17, 2012 5:54:22 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@570c16b7: startup date [Wed Oct 17 17:54:22 CDT 2012]; root of context hierarchy
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.springframework.context.support.AbstractRefreshableApplicationContext.createBeanFactory(AbstractRefreshableApplicationContext.java:195)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:128)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:535)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:449)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at helloworld.HelloWorldTest.main(HelloWorldTest.java:13)
Caused by: java.lang.NullPointerException
at org.springframework.beans.factory.support.DefaultListableBeanFactory.<clinit>(DefaultListableBeanFactory.java:105)
... 7 more
Run Code Online (Sandbox Code Playgroud)
我的配置XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="messageContainer" class="helloworld.MessageContainer">
<property name="message" value="Hello World">
</property>
</bean>
<bean id="messageOutputService" class="helloworld.MessageOutputService">
</bean>
Run Code Online (Sandbox Code Playgroud)
我的考试班.
package helloworld;
import org.springframework.context.ApplicationContext; …Run Code Online (Sandbox Code Playgroud) 我之前在这些论坛上看过这个基本问题,但没有一个答案似乎解决了我的特定问题.无论如何,我有一个小的Spring webapp,包括一个核心Spring业务层,SpringMVC和Spring-Quartz(我也使用MyBatis,虽然我不相信这是相关的).我的所有Spring库都是3.1.3
问题是,当我将我的应用程序部署到Tomcat 6时,通常会将根应用程序上下文和Web应用程序上下文分别初始化两次.通过查看日志可以看出这一点,而且当我的Quartz作业应该触发一次时触发两次这一事实也很明显(后一点是为什么这不仅仅是一个理论问题).
我以为我的应用程序上下文都已整理好了,但显然必定会有一些我不知道的东西.我的一般方法是:
下面是我的配置文件,减去所有的XML文件:
UsMain-servlet.xml中
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:resources mapping="/rsc/**" location="/rsc/" cache-period="31556926"/>
<mvc:annotation-driven />
<context:component-scan base-package="com.me.controllers" />
Run Code Online (Sandbox Code Playgroud)
web.xml中
<web-app ... version="2.5">
...
<servlet>
<servlet-name>UsMain</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>UsMain</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
Run Code Online (Sandbox Code Playgroud)
applicationContext.xml中
<import resource="classes/com/me/config/spring-biz-context.xml" />
<import resource="classes/com/me/config/spring-quartz-context.xml" /> …Run Code Online (Sandbox Code Playgroud) 我们要为使用JSF2.0,Hibernate,MySQL设计的Web应用程序启用UTF-8字符编码.
以下是我们的应用程序上下文文件中定义的数据源
<bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/dbname" />
<property name="maxPoolSize" value="10" />
<property name="maxStatements" value="0" />
<property name="minPoolSize" value="5" />
<property name="useUnicode" value="yes" />
<property name="characterEncoding" value="UTF-8" />
</bean>
Run Code Online (Sandbox Code Playgroud)
在运行应用程序时,我们遇到了异常
Error creating bean with name 'SessionFactory' defined in ServletContext resource [/WEB-INF/classes/applicationContext.xml]: Cannot resolve reference to bean 'DataSource' Error creating bean with name 'DataSource' defined in ServletContext resource [/WEB-INF/classes/applicationContext.xml]: Invalid property 'useUnicode' of bean class [com.mchange.v2.c3p0.ComboPooledDataSource]: Bean property 'useUnicode' is not writable or has an …Run Code Online (Sandbox Code Playgroud) 现在我有一个完整的项目,我想在maven中并行测试.如果我设置并行选项,则我的测试失败原因DirtiesContexts.(即使我注释了测试类@DirtiesContext(classMode=ClassMode.AFTER_CLASS))
我没有把堆栈跟踪放在这里,但它无法加载applicationcontext,导致他无法注册applicationcontext,因为它已经存在.
如果我使用reusefork,即使没有注释,测试也会成功DirtiesContext.
当您使用reusefork时,您将为每个fork创建总是新的VM(这就是它成功的原因).(请参阅此处的文档:http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html)
通过并行,您不会这样做,所以通常这将需要更少的资源.
那么现在问题是:
DirtiesContext?Thx提前.
我有一个大型应用程序上下文,包含许多上下文文件,使用自动装配和包扫描,启动Web服务,建立与数据库的连接以及外部遗留系统等.我一直在考虑如何改善上下文加载时间,因为它需要一段时间没有真正占用CPU.有没有办法告诉应用程序上下文使用多个线程进行初始化?理论上应该是可能的,因为我们已经定义了依赖关系.我希望并行初始化资源(db,web services和legacy connections).
如果我在多个bean上下文中有多个基于Java的配置文件(例如Security Context和Persistence Context在Spring中),我会导入Root Context使用@Import,那么导入的顺序和在哪个配置中扫描自动Components 连线到这些配置文件是否重要?
我敢肯定,Spring将实例化并初始化所有内容,然后自动将任何内容自动链接到基础结构组件,但是自动链接到配置使我感到担忧,因为自动链接发生在整个上下文创建完成之前。这种自动装配可能会引发依赖性问题,还是Spring会处理所有问题?
我在以下配置中未实例化UserService的奇怪异常
@Configuration
@ComponentScan(basePackageClasses = {
UserDao.class,
UserManager.class,
StatefulUserServiceImpl.class,
UserService.class
})
@Import({
PersistenceContext.class,
SecurityConfig.class,
})
public class RootConfig {
}
Run Code Online (Sandbox Code Playgroud)
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = {
UserService.class,
UserManager.class
})
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserManager users;
@Autowired
private UserService userAuthenticationService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userAuthenticationService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().and()
.authorizeRequests()
.antMatchers("/init").permitAll() …Run Code Online (Sandbox Code Playgroud) spring dependency-injection spring-security autowired applicationcontext
可以在@Autowired类和@QualifierSpring中使用bean 。
如何以编程方式做同样的事情?即搜索上下文的bean给它的类和限定符?
我看到了很多getBean()方法,但没有一个方法明确声明它可以做到这一点。
这个类位于我的测试层次结构的顶部:
@TestPropertySource("/test.properties")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public abstract class ApplicationAbstractTest {
}
Run Code Online (Sandbox Code Playgroud)
还有更少的测试类:
@WebAppConfiguration
@ActiveProfiles("mysql")
abstract public class AbstractControllerTest extends ApplicationAbstractTest {
protected MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@PostConstruct
private void postConstruct() {
mockMvc = MockMvcBuilders
.webAppContextSetup(webApplicationContext)
.apply(springSecurity())
.build();
}
}
Run Code Online (Sandbox Code Playgroud)
JsonUserServiceTest:
@ActiveProfiles("json")
public class JsonUserServiceTest extends ApplicationAbstractTest {
@Before
public void setUp() throws Exception {
...
}
}
Run Code Online (Sandbox Code Playgroud)
ContactControllerTest:
public class ContactControllerTest extends AbstractControllerTest {
@Test
public void testGet() throws Exception {
mockMvc.perform(get("/update-" + ID + "-contact")
.with(userAuth(USER)))
// .andExpect(status().isOk()) …Run Code Online (Sandbox Code Playgroud) spring ×7
java ×5
spring-mvc ×2
autowired ×1
constructor ×1
exception ×1
hibernate ×1
jpa ×1
jsf-2 ×1
junit4 ×1
maven ×1
persist ×1
spring-boot ×1
tomcat ×1
unit-testing ×1
utf-8 ×1