복붙노트

[SPRING] Spring-MVC : 훌륭한 인프라 (컨피규레이션) 생성 및 중복 방지

SPRING

Spring-MVC : 훌륭한 인프라 (컨피규레이션) 생성 및 중복 방지

나는 얼마전부터 Spring MVC 애플리케이션을 연구하고있다. 최근에 @Scheduled 메소드에 몇 가지 문제가 발생했으며, 전체 구성이 4 번로드되는 것으로 나타났습니다. 그 때문에 @Scheduled 메소드는 4 번 호출됩니다.

올바르지 않은 3 가지 구성은 NullPointerException (내가 SO에서 말한 것)과 함께 사라지고 그 중 하나는 살아남습니다. 나는 어떻게해야 제대로 프로젝트를 구성 할 수 있는지 알기를 매우 좋아한다. 그래서로드 된 4 가지가 아닌 하나의 구성 만이 Spring의 MVC에 대해 배워야한다.

서블릿 컨텍스트가 크기 때문에 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>

말했듯이 여기에 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
}

나는 자바 파일 전체에서 같은 구조를 유지했다. 내 구성이 1 대신 4 번로드되는 이유는 무엇입니까? 감사.

편집하다

내 서비스는 다음과 같습니다.

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

해결법

  1. ==============================

    1.코드와 구성을 향상시킬 수있는 많은 것들이 있습니다. 당신의 DAO에서 시작하자. Session을 인스턴스 변수에 저장하지 말고 필요한 의존성에 대해 생성자 삽입을 사용하도록 강력히 제안한다. 이것을 고려하여 귀하의 DAO는 이와 같이 보일 것입니다.

    코드와 구성을 향상시킬 수있는 많은 것들이 있습니다. 당신의 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.
        }
    }
    

    더 이상 세터 (특히 세션을위한 것이 아닙니다!) 그냥 평범한 클래스. @Service 클래스도 마찬가지입니다.

    @Service
    @Transactional
    public class CanvasServiceImpl implements CanvasService {
    
        private final CanvasDAO canvasDAO;
    
        public CanvasServiceImpl(CanvasDAO canvasDAO) {
            this.canvasDAO=canvasDAO;
        }
    
        //methods
    }
    

    귀하의 구성에서 모든 @Repository 및 @Service beans를 명시 적으로 정의했습니다. 이미 모든 @Components를 감지하는 도 있습니다. 명시 적으로 선언 된 @Repository 및 @Service beans를 모두 제거하십시오. 이렇게하면 구성이 실제로 정리됩니다.

    최대 절전 모드 구성에서 c3p0과 연결 속성은 DataSource를 주입하고 최대 절전 모드로 관리하지 않지만 Spring은이를 사용할 수 없습니다. 해당 줄을 제거하십시오. 또한 처리 할 각 클래스를 지정하는 대신이 구성을 추가로 정리하면 packagesToScan을 추가하여 @Entity 주석이있는 bean을 자동으로 감지합니다.

    을 사용하여 이미 암시되어 있으므로 기본적으로 내용을 복제하므로 제거 할 수 있습니다.

    이미 에 의해 등록 된 것이 있기 때문에 아무것도하지 않는 RequestMappingHandlerMapping을 명시 적으로 정의했습니다. 메모리 만 차지하므로 MappingJackson2HttpMessageConverter가 자동으로 등록되어 Jackson2가 클래스 경로에서 감지되므로이를 수행 할 필요가 없습니다.

    인터셉터를 요소로 등록하는 것을 잊어 버렸기 때문에 모든 URL에 대해 로케일을 사용할 수 없습니다.

    모든 조언을 수업 및 구성에 적용하면 나머지 구성은 다음과 같습니다.

        <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에 의해로드되는 것에서는 기본적으로 모든 것을 분리해야하지만 @Controllers와 DispatcherServlet에 의해로드되는 것은 @Controllers 및 웹 관련 bean뿐입니다.

    따라서 servlet-context.xml은 이와 같이 보일 것입니다.

        <context:component-scan base-package="com.journaldev.spring" use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
    
        <context:property-placeholder location="classpath:application.properties"/>
    
        <mvc:annotation-driven>
            <mvc:argument-resolvers>
                <beans:bean class="org.springframework.mobile.device.DeviceWebArgumentResolver"/>
            </mvc:argument-resolvers>
        </mvc:annotation-driven>
        <mvc:interceptors>
            <beans:bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor"/>
            <beans:ref bean="localeChangeInterceptor" />
        </mvc:interceptors>
    
        <mvc:default-servlet-handler/>
    
        <resources mapping="/resources/" location="/resources/"/>
    
        <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <beans:property name="prefix" value="/WEB-INF/views/"/>
            <beans:property name="suffix" value=".jsp"/>
        </beans:bean>
    
        <!-- locale -->
        <beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
            <beans:property name="basename" value="classpath:/locale/messages"/>
            <beans:property name="defaultEncoding" value="UTF-8"/>
        </beans:bean>
    
    
        <!-- default locale -->
        <beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
            <beans:property name="defaultLocale" value="de"/>
        </beans:bean>
    
        <!-- Change locale via url. -->
        <beans:bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
            <beans:property name="paramName" value="lang"/>
        </beans:bean>
    
        <beans:bean id="handlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
            <beans:property name="interceptors">
                <beans:list>
                    <beans:ref bean="localeChangeInterceptor"/>
                </beans:list>
            </beans:property>
        </beans:bean>
    
        <beans:bean class="com.journaldev.spring.service.DoNotTruncateMyUrls"/>
    
        <beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <beans:property name="maxUploadSize" value="52428800"/>
        </beans:bean>
    

    그런 다음 제거 된 내용과 (또는 수정)을 root-context.xml에 추가합니다.

    <context:component-scan base-package="com.journaldev.spring">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
    
    <context:property-placeholder location="classpath:application.properties"/>
    
    <beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
                destroy-method="close">
        <beans:property name="driverClassName" value="org.postgresql.Driver"/>
        <beans:property name="url"
                        value="jdbc:postgresql://localhost:5432/dbname"/>
        <beans:property name="username" value="dbuser"/>
        <beans:property name="password" value="dbpass"/>
        <beans:property name="removeAbandoned" value="true"/>
        <beans:property name="removeAbandonedTimeout" value="20"/>
        <beans:property name="defaultAutoCommit" value="false"/>
    </beans:bean>
    
    <!-- Hibernate 4 SessionFactory Bean definition -->
    <beans:bean id="hibernate4AnnotatedSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <beans:property name="dataSource" ref="dataSource"/>
        <beans:property name="packagesToScan" value="com.journaldev.spring.model" />       
        </beans:property>
        <beans:property name="hibernateProperties">
            <beans:props>
                <beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop>
                <beans:prop key="hibernate.show_sql">false</beans:prop>
             <!--   <beans:prop key="hibernate.jdbc.batch_size">1000</beans:prop>
                <beans:prop key="hibernate.order_updates">true</beans:prop>-->
                <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
            </beans:props>
        </beans:property>
    </beans:bean>
    
    <task:annotation-driven/>
    
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
    <beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
    </beans:bean>
    
    <!--  <beans:bean id="bayeux" class="org.cometd.server.BayeuxServerImpl" init-method="start" destroy-method="stop">
          <beans:property name="transports">
              <beans:list>
                  <beans:bean id="jsonTransport" class="org.cometd.server.transport.JSONTransport">
                      <beans:constructor-arg ref="bayeux"/>
                  </beans:bean>
                  <beans:bean id="jsonpTransport" class="org.cometd.server.transport.JSONPTransport">
                      <beans:constructor-arg ref="bayeux"/>
                  </beans:bean>
              </beans:list>
        </beans:property>
      </beans:bean>-->
    

    security-context.xml에서 을 제거하십시오.

    마지막으로 DispatcherServlet이 security-context.xml 대신 servlet-context.xml을로드하게하십시오.

    이제 문맥마다 빈을 두 번로드하지 않으므로 메모리 공간이 줄어들고 더 이상 예약 된 작업이 4 개 없어야합니다. 또한 이메일 클래스는 Spring 관리 빈이어야하며 메일을 간단하게 보내는 JavaMailSender API를 사용하는 것이 좋습니다.

    따라서 기본적으로 앞으로해야 할 일은 주로 물건을 제거하는 것입니다. 코드를 적게 사용하고 구성을 줄이고 동일한 결과를 얻을 수 있습니다.

    더 많은 실습을 원하시면 저는 고용을 원합니다 ...) ...

  2. ==============================

    2.어노테이션 사용의 요지는 xml 설정에 대한 필요성을 제거하는 것입니다. Spring @Service와 @Repository 주석을 사용한다면 위에 게시 된 xml에서 모든 서비스 및 DAO 정의를 제거하고 한 줄로 바꿀 수 있습니다.

    어노테이션 사용의 요지는 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> 
    

    그런 다음 작업을 마치면로드 될 때마다 보안 컨텍스트에서 웹 응용 프로그램 구성을 가져옵니다.

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

    보통 여기에 설명 된대로 구성합니다. 나는 이것이 최선의 관행이라고 생각한다. 본질적으로 Dispatcher 서블릿은 웹 관련 항목 만 초기화합니다. 리스너가 웹 이외의 콘텐츠를 초기화하도록합니다.

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

  3. from https://stackoverflow.com/questions/30399338/spring-mvc-creating-a-good-infrastructureconfiguration-and-avoiding-duplicat by cc-by-sa and MIT license