当前位置: 首页 > 面试题库 >

Spring-MVC:创建良好的基础架构(配置)并避免重复

周滨海
2023-03-14
问题内容

从一段时间开始,我就在开发Spring-MVC应用程序。最近,我遇到了@Scheduled方法的一些问题,并且我注意到整个配置被加载了4次。因此,@
Scheduled方法被调用了4次。

这3种不正确的配置会因NullPointerException(我在SO上被告知)而消失,并且其中一种幸存。我非常想知道如何正确配置项目,因此只加载了一种配置,而不是4种,并在此过程中了解了Spring-
MVC。

由于servlet上下文很大,因此我将web.xml发布到pastebin上,因此我也可以放置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>

如前所述,这是web.xml的URL,这是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;
    }
}

问题答案:

您的代码和配置可以改善很多方面。让我们从您的dao开始,不要将Sessionin
存储在实例变量中,我强烈建议对所需的依赖项使用构造函数注入。考虑到这一点,您的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.
    }
}

No more setters (especially not for the Session!) just a plain class. The
same applies for the @Service classes.

@Service
@Transactional
public class CanvasServiceImpl implements CanvasService {

    private final CanvasDAO canvasDAO;

    public CanvasServiceImpl(CanvasDAO canvasDAO) {
        this.canvasDAO=canvasDAO;
    }

    //methods
}

In your configuration you have explicitly defined all your @Repository and
@Service beans. You also have a <context:component-scan /> which already
detects all @Components. Remove all explicitly declared @Repository and
@Service beans. This will really clean up your configuration!.

In your hibernate configuration the c3p0 and connection properties are
useless as you are injecting a DataSource and hibernate is’t managing it but
Spring is. Remove those lines. Also to cleanup this configuration further
instead of specifying each and every class it needs to proces add
packagesToScan so it will automatically detect @Entity annotated beans.

<context:annotation-config /> is already implied by the use of
<context:component-scan /> so you can remove it as it basically duplicates
things.

You have explicitly defined a RequestMappingHandlerMapping which doesn’t do
anything as there is already one registered by <mvc:annotation-driven />. It
only takes up memory, the MappingJackson2HttpMessageConverter is registered
automatically of Jackson2 is detected on the class path so no need to do that.

Chancing the Locale doesn’t work for all URLs as you forgot to register the
interceptor with the <mvc:annotation-driven /> element.

When applying all that advice to your classes and configuration the remaining
configuration looks like this.

    <context:component-scan base-package="com.journaldev.spring"/>
    <context:property-placeholder location="classpath:application.properties"/>

    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <beans:bean 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>

However you really should split things up in what is loaded by the
ContextLoaderListener basically everything BUT @Controllers and what is
loaded by the DispatcherServlet just @Controllers and web related beans.

So the servlet-context.xml should look something like this.

    <context:component-scan base-package="com.journaldev.spring" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <context:property-placeholder location="classpath:application.properties"/>

    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <beans:bean 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>

Then add what was removed and a <context:component-scan /> (or modify it) to
the root-context.xml.

<context:component-scan base-package="com.journaldev.spring">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

<context:property-placeholder location="classpath:application.properties"/>

<beans:bean id="dataSource" 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>-->

Remove the <import resource="servlet-context.xml" /> from your security- context.xml.

Finally let the DispatcherServlet load the servlet-context.xml instead of
the security-context.xml.

Now as you aren’t loading beans twice per context anymore you should have a
reduced memory footprint and you shouldn’t have 4 scheduled jobs any more.
Also your Email class should, ideally, also be a Spring managed bean and I
would suggest using the JavaMailSender API which simplifies sending emails.

So basically the task ahead for you is to mainly remove things, you will end
up with less code and less configuration and still achieve the same.

For more hands-on-advice I’m for hire ;)…



 类似资料:
  • 本文向大家介绍kafka基础架构相关面试题,主要包含被问及kafka基础架构时的应答技巧和注意事项,需要的朋友参考一下 1)Producer :消息生产者,就是向kafka broker发消息的客户端; 2)Consumer :消息消费者,向kafka broker取消息的客户端; 3)Consumer Group (CG):消费者组,由多个consumer组成。消费者组内每个消费者负责消费不同分

  • 正如我们之后的详细描述 (参见第55章,构建的生命周期), Gradle 有一个配置阶段和执行阶段. 在配置阶段后, Gradle 将会知道应执行的所有任务. Gradle 为你提供一个”钩子”, 以便利用这些信息. 举个例子, 判断发布的任务是否在要被执行的任务当中. 根据这一点, 你可以给一些变量指定不同的值. 在接下来的例子中, distribution 任务和 release 任务将根据变

  • M称为M odel V iew C ontroller或MVC ,是用于开发Web应用程序的软件设计模式。 模型视图控制器模式由以下三个部分组成 - Model - 负责维护数据的模式的最低级别。 View - 负责向用户显示全部或部分数据。 Controller - 控制模型和视图之间交互的软件代码。 MVC很受欢迎,因为它将应用程序逻辑与用户界面层隔离开来,并支持关注点的分离。 Control

  • Java虚拟机简介 “Java虚拟机”可能指如下三个不同的东西 抽象规范 一个具体的实现 一个运行中的虚拟机实例 每个Java程序都运行在某个具体的Java虚拟机实现的实例上。一个Java虚拟机的实例负责运行一个Java程序。当启动一个Java程序的时候,一个虚拟机的实例也就诞生了。当该程序关闭退出时,这个虚拟机实例也就随之消亡。 线程介绍 在Java虚拟机内部有两种线程: 守护线程:通常是由虚拟

  • 这是AWS EC2的基本结构,其中EC2代表Elastic Compute Cloud。 EC2允许用户根据需要使用不同配置的虚拟机。 它允许各种配置选项,单个服务器的映射,各种定价选项等。我们将在AWS产品部分详细讨论这些。 以下是架构的图示。 Note - 在上图中, S3代表简单存储服务。 它允许用户使用API​​调用存储和检索各种类型的数据。 它不包含任何计算元素。 我们将在AWS产品部分