Spring-MVC:创建良好的基础架构(配置)并避免重复
Spring-MVC : Creating a good infrastructure(configuration) and avoiding duplicates
我一直在开发 Spring-MVC 应用程序。最近我 运行 遇到了一些 @Scheduled 方法的问题,我注意到整个配置被加载了 4 次。因此,@Scheduled 方法被调用了 4 次。
3 个不正确的配置因 NullPointerException 而消失(我在 SO 上被告知),一个幸存。我非常想知道如何正确配置我的项目,所以只有一个配置被加载,而不是 4 个,并在此过程中了解 Spring-MVC,Spring。
由于 servlet-context 很大,我在 pastebin 上发布 web.xml,所以我也可以有地方放置 JAVA 代码。
Servlet-context.xml :
<context:annotation-config/>
<mvc:annotation-driven>
<mvc:argument-resolvers>
<beans:bean class="org.springframework.mobile.device.DeviceWebArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:interceptors>
<beans:bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor"/>
</mvc:interceptors>
<mvc:default-servlet-handler/>
<resources mapping="/resources/" location="/resources/"/>
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/"/>
<beans:property name="suffix" value=".jsp"/>
</beans:bean>
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
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"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource"/>
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.journaldev.spring.model.Person</beans:value>
<beans:value>com.journaldev.spring.model.Notes</beans:value>
<beans:value>com.journaldev.spring.model.Canvas</beans:value>
<beans:value>com.journaldev.spring.model.Section</beans:value>
<beans:value>com.journaldev.spring.model.Attachment</beans:value>
<beans:value>com.journaldev.spring.model.GroupAccount</beans:value>
<beans:value>com.journaldev.spring.model.GroupMembers</beans:value>
<beans:value>com.journaldev.spring.model.GroupCanvas</beans:value>
<beans:value>com.journaldev.spring.model.GroupSection</beans:value>
<beans:value>com.journaldev.spring.model.GroupNotes</beans:value>
<beans:value>com.journaldev.spring.model.GroupAttachments
</beans:value>
<beans:value>com.journaldev.spring.model.Token</beans:value>
<beans:value>com.journaldev.spring.model.WaitingMembers
</beans:value>
<beans:value>com.journaldev.spring.model.NoteHistory</beans:value>
<beans:value>com.journaldev.spring.model.GroupNoteHistory
</beans:value>
<beans:value>com.journaldev.spring.model.Feedback</beans:value>
<beans:value>com.journaldev.spring.model.UnreadNotes</beans:value>
<beans:value>com.journaldev.spring.model.SessionState</beans:value>
<beans:value>com.journaldev.spring.model.FeatureRequest
</beans:value>
<beans:value>com.journaldev.spring.model.FeatureComment
</beans:value>
<beans:value>com.journaldev.spring.model.FeatureLike</beans:value>
<beans:value>com.journaldev.spring.model.OnlineUsers</beans:value>
<beans:value>com.journaldev.spring.model.NoteCount</beans:value>
<beans:value>com.journaldev.spring.model.NoteLock</beans:value>
<beans:value>com.journaldev.spring.model.ChatMessages</beans:value>
<beans:value>com.journaldev.spring.model.Conversation</beans:value>
<beans:value>com.journaldev.spring.model.Replies</beans:value>
<beans:value>com.journaldev.spring.model.Notification</beans:value>
<beans:value>com.journaldev.spring.model.Statistics</beans:value>
<beans:value>com.journaldev.spring.model.PrivateChannel</beans:value>
<beans:value>com.journaldev.spring.model.GroupChannels</beans:value>
</beans:list>
</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="connection.pool_size">200</beans:prop>
<beans:prop key="c3p0.max_size">200</beans:prop>
<beans:prop key="c3p0.timeout">1000</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"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<!-- Person beans being here -->
<beans:bean id="personDAO" class="com.journaldev.spring.dao.PersonDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="personService"
class="com.journaldev.spring.service.PersonServiceImpl">
<beans:property name="personDAO" ref="personDAO"/>
</beans:bean>
<!-- <beans:bean id="bayeux" class="org.cometd.server.BayeuxServerImpl" init-method="start" destroy-method="stop">
<beans:property name="transports">
<beans:list>
<beans:bean id="jsonTransport" class="org.cometd.server.transport.JSONTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
<beans:bean id="jsonpTransport" class="org.cometd.server.transport.JSONPTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
</beans:list>
</beans:property>
</beans:bean>-->
<!-- Group Account beans begin here -->
<beans:bean id="groupAccountDAO"
class="com.journaldev.spring.dao.GroupAccountDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupAccountService"
class="com.journaldev.spring.service.GroupAccountServiceImpl">
<beans:property name="groupAccountDAO" ref="groupAccountDAO"/>
</beans:bean>
<!--Group Members bean begin here -->
<beans:bean id="groupMembersDAO"
class="com.journaldev.spring.dao.GroupMembersDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupMembersService"
class="com.journaldev.spring.service.GroupMembersServiceImpl">
<beans:property name="groupMembersDAO" ref="groupMembersDAO"/>
</beans:bean>
<!-- Notes bean begin here -->
<beans:bean id="notesDAO" class="com.journaldev.spring.dao.NotesDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="notesService"
class="com.journaldev.spring.service.NotesServiceImpl">
<beans:property name="notesDAO" ref="notesDAO"/>
</beans:bean>
<!--GroupNotes begin here -->
<beans:bean id="groupNotesDAO" class="com.journaldev.spring.dao.GroupNotesDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupNotesService"
class="com.journaldev.spring.service.GroupNotesServiceImpl">
<beans:property name="groupNotesDAO" ref="groupNotesDAO"/>
</beans:bean>
<!-- Canvas Beans begin here -->
<beans:bean id="canvasDAO" class="com.journaldev.spring.dao.CanvasDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="canvasService"
class="com.journaldev.spring.service.CanvasServiceImpl">
<beans:property name="canvasDAO" ref="canvasDAO"/>
</beans:bean>
<!--Group Canvas beans begin here -->
<beans:bean id="groupCanvasDAO"
class="com.journaldev.spring.dao.GroupCanvasDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupCanvasService"
class="com.journaldev.spring.service.GroupCanvasServiceImpl">
<beans:property name="groupCanvasDAO" ref="groupCanvasDAO"/>
</beans:bean>
<!-- Section beans begin here -->
<beans:bean id="sectionDAO" class="com.journaldev.spring.dao.SectionDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="sectionService"
class="com.journaldev.spring.service.SectionServiceImpl">
<beans:property name="sectionDAO" ref="sectionDAO"/>
</beans:bean>
<!-- Group Section beans begin here -->
<beans:bean id="groupSectionDAO"
class="com.journaldev.spring.dao.GroupSectionDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupSectionService"
class="com.journaldev.spring.service.GroupSectionServiceImpl">
<beans:property name="groupSectionDAO" ref="groupSectionDAO"/>
</beans:bean>
<beans:bean id="tokenDAO" class="com.journaldev.spring.dao.TokenDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="tokenService"
class="com.journaldev.spring.service.TokenServiceImpl">
<beans:property name="tokenDAO" ref="tokenDAO"/>
</beans:bean>
<beans:bean id="attachDAO" class="com.journaldev.spring.dao.AttachmentDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="attachService"
class="com.journaldev.spring.service.AttachmentServiceImpl">
<beans:property name="attachmentDAO" ref="attachDAO"/>
</beans:bean>
<beans:bean id="mattachDAO"
class="com.journaldev.spring.dao.GroupAttachmentsDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="mattachService"
class="com.journaldev.spring.service.GroupAttachmentsServiceImpl">
<beans:property name="groupAttachmentsDAO" ref="mattachDAO"/>
</beans:bean>
<beans:bean id="waitingDAO"
class="com.journaldev.spring.dao.WaitingMembersDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="waitingService"
class="com.journaldev.spring.service.WaitingMembersServiceImpl">
<beans:property name="waitingMembersDAO" ref="waitingDAO"/>
</beans:bean>
<beans:bean id="historyDAO"
class="com.journaldev.spring.dao.NoteHistoryDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="historyService"
class="com.journaldev.spring.service.NoteHistoryServiceImpl">
<beans:property name="noteHistoryDAO" ref="historyDAO"/>
</beans:bean>
<beans:bean id="mhistoryDAO"
class="com.journaldev.spring.dao.GroupNoteHistoryDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="mhistoryService"
class="com.journaldev.spring.service.GroupNoteHistoryServiceImpl">
<beans:property name="groupNoteHistoryDAO" ref="mhistoryDAO"/>
</beans:bean>
<beans:bean id="feedbackDAO" class="com.journaldev.spring.dao.FeedbackDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="feedbackService"
class="com.journaldev.spring.service.FeedbackServiceImpl">
<beans:property name="feedbackDAO" ref="feedbackDAO"/>
</beans:bean>
<beans:bean id="unreadDAO"
class="com.journaldev.spring.dao.UnreadNotesDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="unreadService"
class="com.journaldev.spring.service.UnreadNotesServiceImpl">
<beans:property name="unreadNotesDAO" ref="unreadDAO"/>
</beans:bean>
<beans:bean id="sessionStateDAO"
class="com.journaldev.spring.dao.SessionStateDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="sessionService"
class="com.journaldev.spring.service.SessionStateServiceImpl">
<beans:property name="sessionStateDAO" ref="sessionStateDAO"/>
</beans:bean>
<beans:bean id="featuresDAO"
class="com.journaldev.spring.dao.FeatureRequestDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="featuresService"
class="com.journaldev.spring.service.FeatureRequestServiceImpl">
<beans:property name="featureRequestDAO" ref="featuresDAO"/>
</beans:bean>
<beans:bean id="featureCommentDAO"
class="com.journaldev.spring.dao.FeatureCommentDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="featureCommentService"
class="com.journaldev.spring.service.FeatureCommentServiceImpl">
<beans:property name="featureCommentDAO" ref="featureCommentDAO"/>
</beans:bean>
<beans:bean id="featureLikeDAO"
class="com.journaldev.spring.dao.FeatureLikeDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="featureLikeService"
class="com.journaldev.spring.service.FeatureLikeServiceImpl">
<beans:property name="featureLikeDAO" ref="featureLikeDAO"/>
</beans:bean>
<beans:bean id="onlineUsersDAO"
class="com.journaldev.spring.dao.OnlineUsersDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="onlineUsersService"
class="com.journaldev.spring.service.OnlineUsersServiceImpl">
<beans:property name="onlineUsersDAO" ref="onlineUsersDAO"/>
</beans:bean>
<beans:bean id="noteCountDAO" class="com.journaldev.spring.dao.NoteCountDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="noteCountService"
class="com.journaldev.spring.service.NoteCountServiceImpl">
<beans:property name="noteCountDAO" ref="noteCountDAO"/>
</beans:bean>
<beans:bean id="noteLockDAO" class="com.journaldev.spring.dao.NoteLockDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="noteLockService"
class="com.journaldev.spring.service.NoteLockServiceImpl">
<beans:property name="noteLockDAO" ref="noteLockDAO"/>
</beans:bean>
<beans:bean id="chatDAO" class="com.journaldev.spring.dao.ChatMessagesDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="chatService" class="com.journaldev.spring.service.ChatMessagesServiceImpl">
<beans:property name="chatDAO" ref="chatDAO"/>
</beans:bean>
<beans:bean id="conversationDAO" class="com.journaldev.spring.dao.ConversationDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="conversationService" class="com.journaldev.spring.service.ConversationServiceImpl">
<beans:property name="conversationDAO" ref="conversationDAO"/>
</beans:bean>
<beans:bean id="repliesDAO" class="com.journaldev.spring.dao.RepliesDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="repliesService" class="com.journaldev.spring.service.RepliesServiceImpl">
<beans:property name="repliesDAO" ref="repliesDAO"/>
</beans:bean>
<beans:bean id="notificationDAO" class="com.journaldev.spring.dao.NotificationDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="notificationService" class="com.journaldev.spring.service.NotificationServiceImpl">
<beans:property name="notificationDAO" ref="notificationDAO"/>
</beans:bean>
<beans:bean id="statisticsDAO" class="com.journaldev.spring.dao.StatisticsDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="statisticsService" class="com.journaldev.spring.service.StatisticsServiceImpl">
<beans:property name="statisticsDAO" ref="statisticsDAO"/>
</beans:bean>
<beans:bean id="privateChannelDAO" class="com.journaldev.spring.dao.PrivateChannelDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="privateChannelService" class="com.journaldev.spring.service.PrivateChannelServiceImpl">
<beans:property name="privateChannelDAO" ref="privateChannelDAO"/>
</beans:bean>
<beans:bean id="groupChannelsDAO" class="com.journaldev.spring.dao.GroupChannelsDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupChannelsService" class="com.journaldev.spring.service.GroupChannelsServiceImpl">
<beans:property name="groupChannelsDAO" ref="groupChannelsDAO"/>
</beans:bean>
<!--<beans:bean id="chatBean" class="com.journaldev.spring.chat.ChatServiceImpl"/>-->
<!--Login bean -->
<beans:bean id="LoginServiceImpl"
class="com.journaldev.spring.service.LoginServiceImpl"/>
<context:component-scan base-package="com.journaldev.spring"/>
<!-- locale -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:/locale/messages"/>
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<context:property-placeholder location="classpath:application.properties"/>
<!-- default locale -->
<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<beans:property name="defaultLocale" value="de"/>
</beans:bean>
<!-- Change locale via url. -->
<beans:bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang"/>
</beans:bean>
<beans:bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<beans:property name="interceptors">
<beans:list>
<beans:ref bean="localeChangeInterceptor"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean class="com.journaldev.spring.service.DoNotTruncateMyUrls"/>
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="52428800"/>
</beans:bean>
<beans:bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters" ref="jsonMessageConverter"/>
</beans:bean>
<beans:bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</beans:beans>
如前所述,here is the URL for web.xml and here 是安全应用程序。context.xml
在整个项目中,模型如下所示:
@Entity
@Table(name = "canvas")
public class Canvas {
@Id
@Column(name="canvasid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "canvas_gen")
@SequenceGenerator(name = "canvas_gen",sequenceName = "canvas_seq")
@Index(name = "canvasid")
private int canvasid;
//Other variables, mappings, getters, setters
}
DAO 在整个项目中看起来像这样:
@Transactional
@Repository
public class CanvasDAOImpl implements CanvasDAO{
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sf){
this.sessionFactory = sf;
}
private Session session;
public void setSession(Session session){this.session = session;}
@overrride
public returnType methodName(params..){
session = this.sessionFactory.getCurrentSession();
}
}
最后,我的服务层如下所示:
@Service
@Transactional
public class CanvasServiceImpl implements CanvasService {
private CanvasDAO canvasDAO;
public void setCanvasDAO(CanvasDAO canvasDAO) {
this.canvasDAO = canvasDAO;
}
//methods
}
我在整个 java 文件中保持了相同的结构。为什么我的配置加载了 4 次而不是 1 次。任何关于优化的总体建议。谢谢。
编辑
我的服务是这样的:
@Service
@Transactional
public class AttachmentServiceImpl implements AttachmentService{
@Autowired
private AttachmentDAO attachmentDAO;
// The guy below stays or not? why?
public void setAttachmentDAO(AttachmentDAO attachmentDAO){
this.attachmentDAO = attachmentDAO;
}
}
使用注释的目的是消除对 xml 配置的需要。如果您正在使用 Spring @Service
和 @Repository
注释,那么您可以从上面发布的 xml 中删除所有服务和 dao 定义,并将它们替换为一行。
<context:component-scan base-package="x.y.z.service, x.y.z.repository" />
然后您可以使用 @Autowired
注释将所有服务 类 更新为如下所示,以便 Spring 注入相关的 DAO:
@Service
@Transactional
public class CanvasServiceImpl implements CanvasService {
@Autowired
private CanvasDAO canvasDAO;
}
您还在 web.xml 中多次加载 Spring 安全上下文。一次通过 ContextLoaderListener 一次通过 RequestDispatcher 配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml,/WEB-INF/spring/appServlet/security-applicationContext.xml</param-value>
</context-param>
<session-config>
<session-timeout>1440</session-timeout>
</session-config>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
...
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/security-applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
</web-app>
然后,为了完成任务,您还需要在每次加载时在安全上下文中导入 Web 应用程序配置。
<import resource="servlet-context.xml" />
我通常会按照此处所述进行配置。我相信这被认为是最佳实践。本质上,您让 Dispatcher Servlet 仅初始化与 Web 相关的内容。您让监听器初始化非网络内容。
http://simone-folino.blogspot.co.uk/2012/05/dispatcherservlet-vs.html
您的代码和配置可以改进很多东西。让我们从你的 dao 开始,不要将 Session
存储在实例变量中,我强烈建议对所需的依赖项使用构造函数注入。考虑到这一点,您的 dao(s) 应该看起来像这样。
@Transactional
@Repository
public 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.
}
}
没有更多的二传手(尤其是 Session
!)只是一个普通的 class。这同样适用于 @Service
classes.
@Service
@Transactional
public class CanvasServiceImpl implements CanvasService {
private final CanvasDAO canvasDAO;
public CanvasServiceImpl(CanvasDAO canvasDAO) {
this.canvasDAO=canvasDAO;
}
//methods
}
在您的配置中,您已经明确定义了所有 @Repository
和 @Service
beans。您还有一个 <context:component-scan />
,它已经检测到所有 @Component
。删除所有显式声明的 @Repository
和 @Service
beans。这将真正清理您的配置!
在你的休眠配置中,c3p0
和 connection
属性是无用的,因为你正在注入一个 DataSource
并且休眠不管理它,但 Spring 是。删除那些行。此外,为了进一步清理此配置,而不是指定每个 class 它需要处理添加 packagesToScan
以便它会自动检测 @Entity
注释 bean。
<context:annotation-config />
已经暗示了 <context:component-scan />
的使用,所以你可以删除它,因为它基本上是重复的东西。
您已经明确定义了一个 RequestMappingHandlerMapping
,它什么都不做,因为 <mvc:annotation-driven />
已经注册了一个。它只占用内存,MappingJackson2HttpMessageConverter
是自动注册的 Jackson2 在 class 路径上检测到,所以不需要这样做。
机会 Locale
不适用于所有 URL,因为您忘记了使用 <mvc:annotation-driven />
元素注册拦截器。
将所有建议应用于您的 classes 和配置时,剩余的配置如下所示。
<context:component-scan base-package="com.journaldev.spring"/>
<context:property-placeholder location="classpath:application.properties"/>
<mvc:annotation-driven>
<mvc:argument-resolvers>
<beans:bean class="org.springframework.mobile.device.DeviceWebArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:interceptors>
<beans:bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor"/>
<beans:ref bean="localeChangeInterceptor" />
</mvc:interceptors>
<mvc:default-servlet-handler/>
<resources mapping="/resources/" location="/resources/"/>
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/"/>
<beans:property name="suffix" value=".jsp"/>
</beans:bean>
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
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" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<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" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<!-- <beans:bean id="bayeux" class="org.cometd.server.BayeuxServerImpl" init-method="start" destroy-method="stop">
<beans:property name="transports">
<beans:list>
<beans:bean id="jsonTransport" class="org.cometd.server.transport.JSONTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
<beans:bean id="jsonpTransport" class="org.cometd.server.transport.JSONPTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
</beans:list>
</beans:property>
</beans:bean>-->
<!-- locale -->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:/locale/messages"/>
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<!-- default locale -->
<beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<beans:property name="defaultLocale" value="de"/>
</beans:bean>
<!-- Change locale via url. -->
<beans:bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang"/>
</beans:bean>
<beans:bean id="handlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<beans:property name="interceptors">
<beans:list>
<beans:ref bean="localeChangeInterceptor"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean class="com.journaldev.spring.service.DoNotTruncateMyUrls"/>
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="52428800"/>
</beans:bean>
</beans:beans>
但是你真的应该把 ContextLoaderListener
加载的东西分开,基本上除了 @Controller
之外的所有东西和 DispatcherServlet
加载的东西只是 @Controller
s和网络相关的bean。
所以 servlet-context.xml
应该看起来像这样。
<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 class="org.springframework.mobile.device.DeviceWebArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:interceptors>
<beans:bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor"/>
<beans:ref bean="localeChangeInterceptor" />
</mvc:interceptors>
<mvc:default-servlet-handler/>
<resources mapping="/resources/" location="/resources/"/>
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/"/>
<beans:property name="suffix" value=".jsp"/>
</beans:bean>
<!-- locale -->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:/locale/messages"/>
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<!-- default locale -->
<beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<beans:property name="defaultLocale" value="de"/>
</beans:bean>
<!-- Change locale via url. -->
<beans:bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang"/>
</beans:bean>
<beans:bean id="handlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<beans:property name="interceptors">
<beans:list>
<beans:ref bean="localeChangeInterceptor"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean class="com.journaldev.spring.service.DoNotTruncateMyUrls"/>
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="52428800"/>
</beans:bean>
然后将删除的内容和 <context:component-scan />
(或修改它)添加到 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" class="org.apache.commons.dbcp.BasicDataSource"
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" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<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" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<!-- <beans:bean id="bayeux" class="org.cometd.server.BayeuxServerImpl" init-method="start" destroy-method="stop">
<beans:property name="transports">
<beans:list>
<beans:bean id="jsonTransport" class="org.cometd.server.transport.JSONTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
<beans:bean id="jsonpTransport" class="org.cometd.server.transport.JSONPTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
</beans:list>
</beans:property>
</beans:bean>-->
从您的 security-context.xml
中删除 <import resource="servlet-context.xml" />
。
最后让 DispatcherServlet
加载 servlet-context.xml
而不是 security-context.xml
。
现在,因为您不再为每个上下文加载两次 bean,所以您应该减少内存占用,并且您不应该再有 4 个计划作业。此外,理想情况下,您的 Email
class 也应该是一个 Spring 托管 bean,我建议使用 JavaMailSender
API 来简化电子邮件发送。
所以基本上你前面的任务主要是删除东西,你最终会用更少的代码和更少的配置完成同样的事情。
要获得更多实际操作建议,我正在招聘 ;)...
我一直在开发 Spring-MVC 应用程序。最近我 运行 遇到了一些 @Scheduled 方法的问题,我注意到整个配置被加载了 4 次。因此,@Scheduled 方法被调用了 4 次。
3 个不正确的配置因 NullPointerException 而消失(我在 SO 上被告知),一个幸存。我非常想知道如何正确配置我的项目,所以只有一个配置被加载,而不是 4 个,并在此过程中了解 Spring-MVC,Spring。
由于 servlet-context 很大,我在 pastebin 上发布 web.xml,所以我也可以有地方放置 JAVA 代码。
Servlet-context.xml :
<context:annotation-config/>
<mvc:annotation-driven>
<mvc:argument-resolvers>
<beans:bean class="org.springframework.mobile.device.DeviceWebArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:interceptors>
<beans:bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor"/>
</mvc:interceptors>
<mvc:default-servlet-handler/>
<resources mapping="/resources/" location="/resources/"/>
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/"/>
<beans:property name="suffix" value=".jsp"/>
</beans:bean>
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
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"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource"/>
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.journaldev.spring.model.Person</beans:value>
<beans:value>com.journaldev.spring.model.Notes</beans:value>
<beans:value>com.journaldev.spring.model.Canvas</beans:value>
<beans:value>com.journaldev.spring.model.Section</beans:value>
<beans:value>com.journaldev.spring.model.Attachment</beans:value>
<beans:value>com.journaldev.spring.model.GroupAccount</beans:value>
<beans:value>com.journaldev.spring.model.GroupMembers</beans:value>
<beans:value>com.journaldev.spring.model.GroupCanvas</beans:value>
<beans:value>com.journaldev.spring.model.GroupSection</beans:value>
<beans:value>com.journaldev.spring.model.GroupNotes</beans:value>
<beans:value>com.journaldev.spring.model.GroupAttachments
</beans:value>
<beans:value>com.journaldev.spring.model.Token</beans:value>
<beans:value>com.journaldev.spring.model.WaitingMembers
</beans:value>
<beans:value>com.journaldev.spring.model.NoteHistory</beans:value>
<beans:value>com.journaldev.spring.model.GroupNoteHistory
</beans:value>
<beans:value>com.journaldev.spring.model.Feedback</beans:value>
<beans:value>com.journaldev.spring.model.UnreadNotes</beans:value>
<beans:value>com.journaldev.spring.model.SessionState</beans:value>
<beans:value>com.journaldev.spring.model.FeatureRequest
</beans:value>
<beans:value>com.journaldev.spring.model.FeatureComment
</beans:value>
<beans:value>com.journaldev.spring.model.FeatureLike</beans:value>
<beans:value>com.journaldev.spring.model.OnlineUsers</beans:value>
<beans:value>com.journaldev.spring.model.NoteCount</beans:value>
<beans:value>com.journaldev.spring.model.NoteLock</beans:value>
<beans:value>com.journaldev.spring.model.ChatMessages</beans:value>
<beans:value>com.journaldev.spring.model.Conversation</beans:value>
<beans:value>com.journaldev.spring.model.Replies</beans:value>
<beans:value>com.journaldev.spring.model.Notification</beans:value>
<beans:value>com.journaldev.spring.model.Statistics</beans:value>
<beans:value>com.journaldev.spring.model.PrivateChannel</beans:value>
<beans:value>com.journaldev.spring.model.GroupChannels</beans:value>
</beans:list>
</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="connection.pool_size">200</beans:prop>
<beans:prop key="c3p0.max_size">200</beans:prop>
<beans:prop key="c3p0.timeout">1000</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"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<!-- Person beans being here -->
<beans:bean id="personDAO" class="com.journaldev.spring.dao.PersonDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="personService"
class="com.journaldev.spring.service.PersonServiceImpl">
<beans:property name="personDAO" ref="personDAO"/>
</beans:bean>
<!-- <beans:bean id="bayeux" class="org.cometd.server.BayeuxServerImpl" init-method="start" destroy-method="stop">
<beans:property name="transports">
<beans:list>
<beans:bean id="jsonTransport" class="org.cometd.server.transport.JSONTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
<beans:bean id="jsonpTransport" class="org.cometd.server.transport.JSONPTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
</beans:list>
</beans:property>
</beans:bean>-->
<!-- Group Account beans begin here -->
<beans:bean id="groupAccountDAO"
class="com.journaldev.spring.dao.GroupAccountDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupAccountService"
class="com.journaldev.spring.service.GroupAccountServiceImpl">
<beans:property name="groupAccountDAO" ref="groupAccountDAO"/>
</beans:bean>
<!--Group Members bean begin here -->
<beans:bean id="groupMembersDAO"
class="com.journaldev.spring.dao.GroupMembersDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupMembersService"
class="com.journaldev.spring.service.GroupMembersServiceImpl">
<beans:property name="groupMembersDAO" ref="groupMembersDAO"/>
</beans:bean>
<!-- Notes bean begin here -->
<beans:bean id="notesDAO" class="com.journaldev.spring.dao.NotesDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="notesService"
class="com.journaldev.spring.service.NotesServiceImpl">
<beans:property name="notesDAO" ref="notesDAO"/>
</beans:bean>
<!--GroupNotes begin here -->
<beans:bean id="groupNotesDAO" class="com.journaldev.spring.dao.GroupNotesDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupNotesService"
class="com.journaldev.spring.service.GroupNotesServiceImpl">
<beans:property name="groupNotesDAO" ref="groupNotesDAO"/>
</beans:bean>
<!-- Canvas Beans begin here -->
<beans:bean id="canvasDAO" class="com.journaldev.spring.dao.CanvasDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="canvasService"
class="com.journaldev.spring.service.CanvasServiceImpl">
<beans:property name="canvasDAO" ref="canvasDAO"/>
</beans:bean>
<!--Group Canvas beans begin here -->
<beans:bean id="groupCanvasDAO"
class="com.journaldev.spring.dao.GroupCanvasDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupCanvasService"
class="com.journaldev.spring.service.GroupCanvasServiceImpl">
<beans:property name="groupCanvasDAO" ref="groupCanvasDAO"/>
</beans:bean>
<!-- Section beans begin here -->
<beans:bean id="sectionDAO" class="com.journaldev.spring.dao.SectionDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="sectionService"
class="com.journaldev.spring.service.SectionServiceImpl">
<beans:property name="sectionDAO" ref="sectionDAO"/>
</beans:bean>
<!-- Group Section beans begin here -->
<beans:bean id="groupSectionDAO"
class="com.journaldev.spring.dao.GroupSectionDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupSectionService"
class="com.journaldev.spring.service.GroupSectionServiceImpl">
<beans:property name="groupSectionDAO" ref="groupSectionDAO"/>
</beans:bean>
<beans:bean id="tokenDAO" class="com.journaldev.spring.dao.TokenDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="tokenService"
class="com.journaldev.spring.service.TokenServiceImpl">
<beans:property name="tokenDAO" ref="tokenDAO"/>
</beans:bean>
<beans:bean id="attachDAO" class="com.journaldev.spring.dao.AttachmentDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="attachService"
class="com.journaldev.spring.service.AttachmentServiceImpl">
<beans:property name="attachmentDAO" ref="attachDAO"/>
</beans:bean>
<beans:bean id="mattachDAO"
class="com.journaldev.spring.dao.GroupAttachmentsDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="mattachService"
class="com.journaldev.spring.service.GroupAttachmentsServiceImpl">
<beans:property name="groupAttachmentsDAO" ref="mattachDAO"/>
</beans:bean>
<beans:bean id="waitingDAO"
class="com.journaldev.spring.dao.WaitingMembersDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="waitingService"
class="com.journaldev.spring.service.WaitingMembersServiceImpl">
<beans:property name="waitingMembersDAO" ref="waitingDAO"/>
</beans:bean>
<beans:bean id="historyDAO"
class="com.journaldev.spring.dao.NoteHistoryDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="historyService"
class="com.journaldev.spring.service.NoteHistoryServiceImpl">
<beans:property name="noteHistoryDAO" ref="historyDAO"/>
</beans:bean>
<beans:bean id="mhistoryDAO"
class="com.journaldev.spring.dao.GroupNoteHistoryDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="mhistoryService"
class="com.journaldev.spring.service.GroupNoteHistoryServiceImpl">
<beans:property name="groupNoteHistoryDAO" ref="mhistoryDAO"/>
</beans:bean>
<beans:bean id="feedbackDAO" class="com.journaldev.spring.dao.FeedbackDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="feedbackService"
class="com.journaldev.spring.service.FeedbackServiceImpl">
<beans:property name="feedbackDAO" ref="feedbackDAO"/>
</beans:bean>
<beans:bean id="unreadDAO"
class="com.journaldev.spring.dao.UnreadNotesDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="unreadService"
class="com.journaldev.spring.service.UnreadNotesServiceImpl">
<beans:property name="unreadNotesDAO" ref="unreadDAO"/>
</beans:bean>
<beans:bean id="sessionStateDAO"
class="com.journaldev.spring.dao.SessionStateDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="sessionService"
class="com.journaldev.spring.service.SessionStateServiceImpl">
<beans:property name="sessionStateDAO" ref="sessionStateDAO"/>
</beans:bean>
<beans:bean id="featuresDAO"
class="com.journaldev.spring.dao.FeatureRequestDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="featuresService"
class="com.journaldev.spring.service.FeatureRequestServiceImpl">
<beans:property name="featureRequestDAO" ref="featuresDAO"/>
</beans:bean>
<beans:bean id="featureCommentDAO"
class="com.journaldev.spring.dao.FeatureCommentDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="featureCommentService"
class="com.journaldev.spring.service.FeatureCommentServiceImpl">
<beans:property name="featureCommentDAO" ref="featureCommentDAO"/>
</beans:bean>
<beans:bean id="featureLikeDAO"
class="com.journaldev.spring.dao.FeatureLikeDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="featureLikeService"
class="com.journaldev.spring.service.FeatureLikeServiceImpl">
<beans:property name="featureLikeDAO" ref="featureLikeDAO"/>
</beans:bean>
<beans:bean id="onlineUsersDAO"
class="com.journaldev.spring.dao.OnlineUsersDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="onlineUsersService"
class="com.journaldev.spring.service.OnlineUsersServiceImpl">
<beans:property name="onlineUsersDAO" ref="onlineUsersDAO"/>
</beans:bean>
<beans:bean id="noteCountDAO" class="com.journaldev.spring.dao.NoteCountDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="noteCountService"
class="com.journaldev.spring.service.NoteCountServiceImpl">
<beans:property name="noteCountDAO" ref="noteCountDAO"/>
</beans:bean>
<beans:bean id="noteLockDAO" class="com.journaldev.spring.dao.NoteLockDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="noteLockService"
class="com.journaldev.spring.service.NoteLockServiceImpl">
<beans:property name="noteLockDAO" ref="noteLockDAO"/>
</beans:bean>
<beans:bean id="chatDAO" class="com.journaldev.spring.dao.ChatMessagesDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="chatService" class="com.journaldev.spring.service.ChatMessagesServiceImpl">
<beans:property name="chatDAO" ref="chatDAO"/>
</beans:bean>
<beans:bean id="conversationDAO" class="com.journaldev.spring.dao.ConversationDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="conversationService" class="com.journaldev.spring.service.ConversationServiceImpl">
<beans:property name="conversationDAO" ref="conversationDAO"/>
</beans:bean>
<beans:bean id="repliesDAO" class="com.journaldev.spring.dao.RepliesDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="repliesService" class="com.journaldev.spring.service.RepliesServiceImpl">
<beans:property name="repliesDAO" ref="repliesDAO"/>
</beans:bean>
<beans:bean id="notificationDAO" class="com.journaldev.spring.dao.NotificationDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="notificationService" class="com.journaldev.spring.service.NotificationServiceImpl">
<beans:property name="notificationDAO" ref="notificationDAO"/>
</beans:bean>
<beans:bean id="statisticsDAO" class="com.journaldev.spring.dao.StatisticsDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="statisticsService" class="com.journaldev.spring.service.StatisticsServiceImpl">
<beans:property name="statisticsDAO" ref="statisticsDAO"/>
</beans:bean>
<beans:bean id="privateChannelDAO" class="com.journaldev.spring.dao.PrivateChannelDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="privateChannelService" class="com.journaldev.spring.service.PrivateChannelServiceImpl">
<beans:property name="privateChannelDAO" ref="privateChannelDAO"/>
</beans:bean>
<beans:bean id="groupChannelsDAO" class="com.journaldev.spring.dao.GroupChannelsDAOImpl">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<beans:bean id="groupChannelsService" class="com.journaldev.spring.service.GroupChannelsServiceImpl">
<beans:property name="groupChannelsDAO" ref="groupChannelsDAO"/>
</beans:bean>
<!--<beans:bean id="chatBean" class="com.journaldev.spring.chat.ChatServiceImpl"/>-->
<!--Login bean -->
<beans:bean id="LoginServiceImpl"
class="com.journaldev.spring.service.LoginServiceImpl"/>
<context:component-scan base-package="com.journaldev.spring"/>
<!-- locale -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:/locale/messages"/>
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<context:property-placeholder location="classpath:application.properties"/>
<!-- default locale -->
<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<beans:property name="defaultLocale" value="de"/>
</beans:bean>
<!-- Change locale via url. -->
<beans:bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang"/>
</beans:bean>
<beans:bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<beans:property name="interceptors">
<beans:list>
<beans:ref bean="localeChangeInterceptor"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean class="com.journaldev.spring.service.DoNotTruncateMyUrls"/>
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="52428800"/>
</beans:bean>
<beans:bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters" ref="jsonMessageConverter"/>
</beans:bean>
<beans:bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</beans:beans>
如前所述,here is the URL for web.xml and here 是安全应用程序。context.xml
在整个项目中,模型如下所示:
@Entity
@Table(name = "canvas")
public class Canvas {
@Id
@Column(name="canvasid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "canvas_gen")
@SequenceGenerator(name = "canvas_gen",sequenceName = "canvas_seq")
@Index(name = "canvasid")
private int canvasid;
//Other variables, mappings, getters, setters
}
DAO 在整个项目中看起来像这样:
@Transactional
@Repository
public class CanvasDAOImpl implements CanvasDAO{
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sf){
this.sessionFactory = sf;
}
private Session session;
public void setSession(Session session){this.session = session;}
@overrride
public returnType methodName(params..){
session = this.sessionFactory.getCurrentSession();
}
}
最后,我的服务层如下所示:
@Service
@Transactional
public class CanvasServiceImpl implements CanvasService {
private CanvasDAO canvasDAO;
public void setCanvasDAO(CanvasDAO canvasDAO) {
this.canvasDAO = canvasDAO;
}
//methods
}
我在整个 java 文件中保持了相同的结构。为什么我的配置加载了 4 次而不是 1 次。任何关于优化的总体建议。谢谢。
编辑
我的服务是这样的:
@Service
@Transactional
public class AttachmentServiceImpl implements AttachmentService{
@Autowired
private AttachmentDAO attachmentDAO;
// The guy below stays or not? why?
public void setAttachmentDAO(AttachmentDAO attachmentDAO){
this.attachmentDAO = attachmentDAO;
}
}
使用注释的目的是消除对 xml 配置的需要。如果您正在使用 Spring @Service
和 @Repository
注释,那么您可以从上面发布的 xml 中删除所有服务和 dao 定义,并将它们替换为一行。
<context:component-scan base-package="x.y.z.service, x.y.z.repository" />
然后您可以使用 @Autowired
注释将所有服务 类 更新为如下所示,以便 Spring 注入相关的 DAO:
@Service
@Transactional
public class CanvasServiceImpl implements CanvasService {
@Autowired
private CanvasDAO canvasDAO;
}
您还在 web.xml 中多次加载 Spring 安全上下文。一次通过 ContextLoaderListener 一次通过 RequestDispatcher 配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml,/WEB-INF/spring/appServlet/security-applicationContext.xml</param-value>
</context-param>
<session-config>
<session-timeout>1440</session-timeout>
</session-config>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
...
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/security-applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
</web-app>
然后,为了完成任务,您还需要在每次加载时在安全上下文中导入 Web 应用程序配置。
<import resource="servlet-context.xml" />
我通常会按照此处所述进行配置。我相信这被认为是最佳实践。本质上,您让 Dispatcher Servlet 仅初始化与 Web 相关的内容。您让监听器初始化非网络内容。
http://simone-folino.blogspot.co.uk/2012/05/dispatcherservlet-vs.html
您的代码和配置可以改进很多东西。让我们从你的 dao 开始,不要将 Session
存储在实例变量中,我强烈建议对所需的依赖项使用构造函数注入。考虑到这一点,您的 dao(s) 应该看起来像这样。
@Transactional
@Repository
public 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.
}
}
没有更多的二传手(尤其是 Session
!)只是一个普通的 class。这同样适用于 @Service
classes.
@Service
@Transactional
public class CanvasServiceImpl implements CanvasService {
private final CanvasDAO canvasDAO;
public CanvasServiceImpl(CanvasDAO canvasDAO) {
this.canvasDAO=canvasDAO;
}
//methods
}
在您的配置中,您已经明确定义了所有 @Repository
和 @Service
beans。您还有一个 <context:component-scan />
,它已经检测到所有 @Component
。删除所有显式声明的 @Repository
和 @Service
beans。这将真正清理您的配置!
在你的休眠配置中,c3p0
和 connection
属性是无用的,因为你正在注入一个 DataSource
并且休眠不管理它,但 Spring 是。删除那些行。此外,为了进一步清理此配置,而不是指定每个 class 它需要处理添加 packagesToScan
以便它会自动检测 @Entity
注释 bean。
<context:annotation-config />
已经暗示了 <context:component-scan />
的使用,所以你可以删除它,因为它基本上是重复的东西。
您已经明确定义了一个 RequestMappingHandlerMapping
,它什么都不做,因为 <mvc:annotation-driven />
已经注册了一个。它只占用内存,MappingJackson2HttpMessageConverter
是自动注册的 Jackson2 在 class 路径上检测到,所以不需要这样做。
机会 Locale
不适用于所有 URL,因为您忘记了使用 <mvc:annotation-driven />
元素注册拦截器。
将所有建议应用于您的 classes 和配置时,剩余的配置如下所示。
<context:component-scan base-package="com.journaldev.spring"/>
<context:property-placeholder location="classpath:application.properties"/>
<mvc:annotation-driven>
<mvc:argument-resolvers>
<beans:bean class="org.springframework.mobile.device.DeviceWebArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:interceptors>
<beans:bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor"/>
<beans:ref bean="localeChangeInterceptor" />
</mvc:interceptors>
<mvc:default-servlet-handler/>
<resources mapping="/resources/" location="/resources/"/>
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/"/>
<beans:property name="suffix" value=".jsp"/>
</beans:bean>
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
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" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<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" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<!-- <beans:bean id="bayeux" class="org.cometd.server.BayeuxServerImpl" init-method="start" destroy-method="stop">
<beans:property name="transports">
<beans:list>
<beans:bean id="jsonTransport" class="org.cometd.server.transport.JSONTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
<beans:bean id="jsonpTransport" class="org.cometd.server.transport.JSONPTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
</beans:list>
</beans:property>
</beans:bean>-->
<!-- locale -->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:/locale/messages"/>
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<!-- default locale -->
<beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<beans:property name="defaultLocale" value="de"/>
</beans:bean>
<!-- Change locale via url. -->
<beans:bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang"/>
</beans:bean>
<beans:bean id="handlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<beans:property name="interceptors">
<beans:list>
<beans:ref bean="localeChangeInterceptor"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean class="com.journaldev.spring.service.DoNotTruncateMyUrls"/>
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="52428800"/>
</beans:bean>
</beans:beans>
但是你真的应该把 ContextLoaderListener
加载的东西分开,基本上除了 @Controller
之外的所有东西和 DispatcherServlet
加载的东西只是 @Controller
s和网络相关的bean。
所以 servlet-context.xml
应该看起来像这样。
<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 class="org.springframework.mobile.device.DeviceWebArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:interceptors>
<beans:bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor"/>
<beans:ref bean="localeChangeInterceptor" />
</mvc:interceptors>
<mvc:default-servlet-handler/>
<resources mapping="/resources/" location="/resources/"/>
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/"/>
<beans:property name="suffix" value=".jsp"/>
</beans:bean>
<!-- locale -->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:/locale/messages"/>
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<!-- default locale -->
<beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<beans:property name="defaultLocale" value="de"/>
</beans:bean>
<!-- Change locale via url. -->
<beans:bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang"/>
</beans:bean>
<beans:bean id="handlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<beans:property name="interceptors">
<beans:list>
<beans:ref bean="localeChangeInterceptor"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean class="com.journaldev.spring.service.DoNotTruncateMyUrls"/>
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="52428800"/>
</beans:bean>
然后将删除的内容和 <context:component-scan />
(或修改它)添加到 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" class="org.apache.commons.dbcp.BasicDataSource"
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" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<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" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</beans:bean>
<!-- <beans:bean id="bayeux" class="org.cometd.server.BayeuxServerImpl" init-method="start" destroy-method="stop">
<beans:property name="transports">
<beans:list>
<beans:bean id="jsonTransport" class="org.cometd.server.transport.JSONTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
<beans:bean id="jsonpTransport" class="org.cometd.server.transport.JSONPTransport">
<beans:constructor-arg ref="bayeux"/>
</beans:bean>
</beans:list>
</beans:property>
</beans:bean>-->
从您的 security-context.xml
中删除 <import resource="servlet-context.xml" />
。
最后让 DispatcherServlet
加载 servlet-context.xml
而不是 security-context.xml
。
现在,因为您不再为每个上下文加载两次 bean,所以您应该减少内存占用,并且您不应该再有 4 个计划作业。此外,理想情况下,您的 Email
class 也应该是一个 Spring 托管 bean,我建议使用 JavaMailSender
API 来简化电子邮件发送。
所以基本上你前面的任务主要是删除东西,你最终会用更少的代码和更少的配置完成同样的事情。
要获得更多实际操作建议,我正在招聘 ;)...