2015-05-22 1 views
0

Я работаю над приложением Spring-MVC с некоторого времени. Недавно я столкнулся с некоторыми проблемами с методами @Scheduled, и я заметил, что вся конфигурация загружается 4 раза. Из-за этого методы @Scheduled получают вызов 4 раза.Spring-MVC: Создание хорошей инфраструктуры (конфигурации) и избежание дубликатов

3 конфигурации, которые не правильны, вычеркнуть с помощью NullPointerException (это то, о чем мне говорили так), и тот выживает. Мне очень интересно узнать, как я могу правильно настроить свой проект, поэтому загружается только одна конфигурация, а не 4, и узнайте о Spring-MVC, Spring в этом процессе.

Поскольку контекст сервлета большой, я отправляю 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> 

Как уже говорилось, here является URL для web.xml и here является безопасность-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 выглядит следующим образом throughtout проекта:

@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; 
    } 
} 

ответ

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. 
    } 
} 

Нет больше сеттеры (особенно не для Session!) Просто обычный класс. То же самое относится к классам @Service.

@Service 
@Transactional 
public class CanvasServiceImpl implements CanvasService { 

    private final CanvasDAO canvasDAO; 

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

    //methods 
} 

В конфигурации вы четко определены все @Repository и @Service бобы. У вас также есть <context:component-scan />, который уже обнаруживает все @Component s. Удалите все явно объявленные @Repository и @Service бобы. Это действительно очистит вашу конфигурацию !.

В конфигурации спящего режима в c3p0 и connection свойства бесполезны, как вы нагнетание DataSource и зимуют is't управления ею, но весна. Удалите эти строки. Кроме того, для дальнейшей очистки этой конфигурации вместо указания каждого класса, который необходимо обработать, добавьте packagesToScan, чтобы он автоматически обнаружил @Entity аннотированные бобы.

<context:annotation-config /> уже подразумевается использованием <context:component-scan />, поэтому вы можете удалить его, поскольку он в основном дублирует вещи.

Вы явно определили RequestMappingHandlerMapping, который ничего не делает, поскольку уже зарегистрировано <mvc:annotation-driven />. Он занимает только память, MappingJackson2HttpMessageConverter зарегистрирован автоматически из Jackson2, обнаружен на пути к классу, поэтому не нужно этого делать.

Chancing Locale не работает для всех URL-адресов, поскольку вы забыли зарегистрировать перехватчик с помощью элемента <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 s и что загружаемую 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.

Теперь, когда вы больше не загружаете бобы дважды в контексте, вы должны иметь уменьшенный объем памяти, и у вас не должно быть 4 запланированных задания. Также ваш класс Email должен, в идеале, также быть управляемым компонентом Spring, и я бы предложил использовать API JavaMailSender, который упрощает отправку писем.

Так что в основном задача для вас - это в основном удалить вещи, вы получите меньше кода и меньше конфигурации и все равно достигнете того же.

Для более практический совет-я нахожусь в аренду;) ...

+0

Этот ответ был потрясающим. Спасибо, что так много ... я буду держать то, о чем ты сказал. И я уверен, что понял столько, сколько понял через месяц ... Большое спасибо. Я начинаю реализовывать это сейчас. И устройте щедрость. –

+0

Привет, сэр, не могли бы вы проверить этот вопрос относительно Spring-MVC и Maven. http://stackoverflow.com/questions/40125973/spring-maven-nullpointer-exception-when-calling-methods-from-local-spring-mvc. Спасибо. :-) –

3

Точка с помощью аннотаций, чтобы устранить необходимость в конфигурации XML. Если вы используете аннотации Spring @Service и @Repository, вы можете удалить все описания сервисов и дао из размещенного выше xml и заменить их одной строкой.

<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; 
} 

Вы также загрузить контекст безопасности Весны несколько раз в вашей сети .xml. После того, как через 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> 

А потом, чтобы завершить вещи вы также импортировать конфигурацию веб-приложений в контексте безопасности каждый раз, когда он будет загружен.

<import resource="servlet-context.xml" /> 

Я бы обычно сконфигурировал как описано здесь. Я считаю, что это считается лучшей практикой. По сути, у вас есть диспетчерский сервлет, инициализирующий только связанные с Интернетом вещи.У вас есть Listener, инициализирующий не-веб-материал.

http://simone-folino.blogspot.co.uk/2012/05/dispatcherservlet-vs.html

+0

Я меняю его autowired прямо сейчас. Должен ли я удалить его из ContextLoader или RequestDispatcher? –

+0

Я добавил в нижней части основного сообщения некоторый код, можете ли вы, пожалуйста, проверить –

+0

См. Мое обновление в нижней части ответа. –

Смежные вопросы