我正在开发一个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是web.xml的URL,here是security-application.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;
}
}
答案 0 :(得分:3)
使用注释的目的是消除对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相关的东西。你有Listener初始化非web内容。
http://simone-folino.blogspot.co.uk/2012/05/dispatcherservlet-vs.html
答案 1 :(得分:2)
您的代码和配置可以改进很多内容。让我们从您的dao开始,不要将Session
存储在实例变量中,我强烈建议使用构造函数注入来获取所需的依赖项。考虑到这一点你的dao应该看起来像这样。
@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.
}
}
没有更多的setter(尤其不适用于Session
!)只是一个简单的类。这同样适用于@Service
类。
@Service
@Transactional
public class CanvasServiceImpl implements CanvasService {
private final CanvasDAO canvasDAO;
public CanvasServiceImpl(CanvasDAO canvasDAO) {
this.canvasDAO=canvasDAO;
}
//methods
}
在您的配置中,您已明确定义了所有@Repository
和@Service
bean。您还有一个<context:component-scan />
已经检测到所有@Component
。删除所有显式声明的@Repository
和@Service
bean。这将真正清理您的配置!
在你的休眠配置中,c3p0
和connection
属性是无用的,因为你注入DataSource
并且hibernate不是在管理它,而是Spring。删除这些行。此外,要进一步清理此配置,而不是指定处理添加packagesToScan
所需的每个类,以便它自动检测@Entity
带注释的bean。
<context:annotation-config />
已隐含 <context:component-scan />
,因此您可以将其删除,因为它基本上会复制内容。
您已明确定义RequestMappingHandlerMapping
,但由于<mvc:annotation-driven />
已注册了MappingJackson2HttpMessageConverter
,因此无法执行任何操作。它只占用内存,在类路径上检测到Jackson2自动注册Locale
所以不需要这样做。
由于忘记使用<mvc:annotation-driven />
元素注册拦截器,因此对 <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
只加载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>-->
。
<import resource="servlet-context.xml" />
从security-context.xml
中删除DispatcherServlet
。
最后让servlet-context.xml
加载security-context.xml
而不是Email
。
现在,由于您不再为每个上下文加载两次bean,因此应该减少内存占用,并且不应再有4个预定作业。理想情况下,您的JavaMailSender
类也应该是Spring托管bean,我建议使用{{1}} API来简化发送电子邮件。
所以基本上你面前的任务是主要删除东西,你最终会得到更少的代码和更少的配置,但仍然可以实现相同的目标。
如需更多实际操作建议,我可以聘请;)