您的代码和配置可以改善很多方面。让我们从您的dao开始,不要将
Sessionin
存储在实例变量中,我强烈建议对所需的依赖项使用构造函数注入。考虑到这一点,您的dao应该看起来像这样。
@Transactional@Repositorypublic class CanvasDAOImpl implements CanvasDAO{ private final SessionFactory sessionFactory; @Autowired public CanvasDAOImpl(SessionFactory sessionFactory) { this.sessionFactory=sessionFactory; } @overrride public returnType methodName(params..){ Session session = this.sessionFactory.getCurrentSession(); // Do stuff with the session. }}No more setters (especially not for the
Session!) just a plain class. The
same applies for the
@Serviceclasses.
@Service@Transactionalpublic class CanvasServiceImpl implements CanvasService { private final CanvasDAO canvasDAO; public CanvasServiceImpl(CanvasDAO canvasDAO) { this.canvasDAO=canvasDAO; } //methods}In your configuration you have explicitly defined all your
@Repositoryand
@Servicebeans. You also have a
<context:component-scan />which already
detects all
@Components. Remove all explicitly declared
@Repositoryand
@Servicebeans. This will really clean up your configuration!.
In your hibernate configuration the
c3p0and
connectionproperties are
useless as you are injecting a
DataSourceand hibernate is’t managing it but
Spring is. Remove those lines. Also to cleanup this configuration further
instead of specifying each and every class it needs to proces add
packagesToScanso it will automatically detect
@Entityannotated beans.
<context:annotation-config />is already implied by the use of
<context:component-scan />so you can remove it as it basically duplicates
things.
You have explicitly defined a
RequestMappingHandlerMappingwhich doesn’t do
anything as there is already one registered by
<mvc:annotation-driven />. It
only takes up memory, the
MappingJackson2HttpMessageConverteris registered
automatically of Jackson2 is detected on the class path so no need to do that.
Chancing the
Localedoesn’t work for all URLs as you forgot to register the
interceptor with the
<mvc:annotation-driven />element.
When applying all that advice to your classes and configuration the remaining
configuration looks like this.
<context:component-scan base-package="com.journaldev.spring"/> <context:property-placeholder location="classpath:application.properties"/> <mvc:annotation-driven> <mvc:argument-resolvers> <beans:bean /> </mvc:argument-resolvers> </mvc:annotation-driven> <mvc:interceptors> <beans:bean /> <beans:ref bean="localeChangeInterceptor" /> </mvc:interceptors> <mvc:default-servlet-handler/> <resources mapping="/resources/" location="/resources/"/> <beans:bean > <beans:property name="prefix" value="/WEB-INF/views/"/> <beans:property name="suffix" value=".jsp"/> </beans:bean> <beans:bean id="dataSource" destroy-method="close"> <beans:property name="driverClassName" value="org.postgresql.Driver"/> <beans:property name="url" value="jdbc:postgresql://localhost:5432/dbname"/> <beans:property name="username" value="dbuser"/> <beans:property name="password" value="dbpass"/> <beans:property name="removeAbandoned" value="true"/> <beans:property name="removeAbandonedTimeout" value="20"/> <beans:property name="defaultAutoCommit" value="false"/> </beans:bean> <!-- Hibernate 4 SessionFactory Bean definition --> <beans:bean id="hibernate4AnnotatedSessionFactory" > <beans:property name="dataSource" ref="dataSource"/> <beans:property name="packagesToScan" value="com.journaldev.spring.model" /> </beans:property> <beans:property name="hibernateProperties"> <beans:props> <beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop> <beans:prop key="hibernate.show_sql">false</beans:prop> <!-- <beans:prop key="hibernate.jdbc.batch_size">1000</beans:prop> <beans:prop key="hibernate.order_updates">true</beans:prop>--> <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop> </beans:props> </beans:property> </beans:bean> <task:annotation-driven/> <tx:annotation-driven transaction-manager="transactionManager"/> <beans:bean id="transactionManager" > <beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/> </beans:bean> <!-- <beans:bean id="bayeux" init-method="start" destroy-method="stop"> <beans:property name="transports"> <beans:list> <beans:bean id="jsonTransport" ><beans:constructor-arg ref="bayeux"/> </beans:bean> <beans:bean id="jsonpTransport" ><beans:constructor-arg ref="bayeux"/> </beans:bean> </beans:list> </beans:property> </beans:bean>--> <!-- locale --> <beans:bean id="messageSource" > <beans:property name="basename" value="classpath:/locale/messages"/> <beans:property name="defaultEncoding" value="UTF-8"/> </beans:bean> <!-- default locale --> <beans:bean id="localeResolver" > <beans:property name="defaultLocale" value="de"/> </beans:bean> <!-- Change locale via url. --> <beans:bean id="localeChangeInterceptor" > <beans:property name="paramName" value="lang"/> </beans:bean> <beans:bean id="handlerMapping" > <beans:property name="interceptors"> <beans:list> <beans:ref bean="localeChangeInterceptor"/> </beans:list> </beans:property> </beans:bean> <beans:bean /> <beans:bean id="multipartResolver" > <beans:property name="maxUploadSize" value="52428800"/> </beans:bean></beans:beans>
However you really should split things up in what is loaded by the
ContextLoaderListenerbasically everything BUT
@Controllers and what is
loaded by the
DispatcherServletjust
@Controllers and web related beans.
So the
servlet-context.xmlshould look something like this.
<context:component-scan base-package="com.journaldev.spring" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> <context:property-placeholder location="classpath:application.properties"/> <mvc:annotation-driven> <mvc:argument-resolvers> <beans:bean /> </mvc:argument-resolvers> </mvc:annotation-driven> <mvc:interceptors> <beans:bean /> <beans:ref bean="localeChangeInterceptor" /> </mvc:interceptors> <mvc:default-servlet-handler/> <resources mapping="/resources/" location="/resources/"/> <beans:bean > <beans:property name="prefix" value="/WEB-INF/views/"/> <beans:property name="suffix" value=".jsp"/> </beans:bean> <!-- locale --> <beans:bean id="messageSource" > <beans:property name="basename" value="classpath:/locale/messages"/> <beans:property name="defaultEncoding" value="UTF-8"/> </beans:bean> <!-- default locale --> <beans:bean id="localeResolver" > <beans:property name="defaultLocale" value="de"/> </beans:bean> <!-- Change locale via url. --> <beans:bean id="localeChangeInterceptor" > <beans:property name="paramName" value="lang"/> </beans:bean> <beans:bean id="handlerMapping" > <beans:property name="interceptors"> <beans:list> <beans:ref bean="localeChangeInterceptor"/> </beans:list> </beans:property> </beans:bean> <beans:bean /> <beans:bean id="multipartResolver" > <beans:property name="maxUploadSize" value="52428800"/> </beans:bean>
Then add what was removed and a
<context:component-scan />(or modify it) to
the
root-context.xml.
<context:component-scan base-package="com.journaldev.spring"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /></context:component-scan><context:property-placeholder location="classpath:application.properties"/><beans:bean id="dataSource" destroy-method="close"> <beans:property name="driverClassName" value="org.postgresql.Driver"/> <beans:property name="url" value="jdbc:postgresql://localhost:5432/dbname"/> <beans:property name="username" value="dbuser"/> <beans:property name="password" value="dbpass"/> <beans:property name="removeAbandoned" value="true"/> <beans:property name="removeAbandonedTimeout" value="20"/> <beans:property name="defaultAutoCommit" value="false"/></beans:bean><!-- Hibernate 4 SessionFactory Bean definition --><beans:bean id="hibernate4AnnotatedSessionFactory" > <beans:property name="dataSource" ref="dataSource"/> <beans:property name="packagesToScan" value="com.journaldev.spring.model" /></beans:property> <beans:property name="hibernateProperties"> <beans:props> <beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop> <beans:prop key="hibernate.show_sql">false</beans:prop> <!-- <beans:prop key="hibernate.jdbc.batch_size">1000</beans:prop> <beans:prop key="hibernate.order_updates">true</beans:prop>--> <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop> </beans:props> </beans:property></beans:bean><task:annotation-driven/><tx:annotation-driven transaction-manager="transactionManager"/><beans:bean id="transactionManager" > <beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/></beans:bean><!-- <beans:bean id="bayeux" init-method="start" destroy-method="stop"> <beans:property name="transports"> <beans:list> <beans:bean id="jsonTransport" > <beans:constructor-arg ref="bayeux"/> </beans:bean> <beans:bean id="jsonpTransport" > <beans:constructor-arg ref="bayeux"/> </beans:bean> </beans:list> </beans:property> </beans:bean>-->
Remove the
<import resource="servlet-context.xml" />from your
security-context.xml.
Finally let the
DispatcherServletload the
servlet-context.xmlinstead of
the
security-context.xml.
Now as you aren’t loading beans twice per context anymore you should have a
reduced memory footprint and you shouldn’t have 4 scheduled jobs any more.
Also your
would suggest using the
JavaMailSenderAPI which simplifies sending emails.
So basically the task ahead for you is to mainly remove things, you will end
up with less pre and less configuration and still achieve the same.
For more hands-on-advice I’m for hire ;)…



