我正在构建一个基于Spring的应用程序,该应用程序处理移动游戏应用程序的服务器端游戏管理。堆栈是Spring / Hibernate / Jersey。我希望客户端(移动设备)调用REST API来更新/获取游戏状态。
我创建了一个TournamentController班级,负责使用一些业务逻辑来更新比赛状态。该类旨在在每次需要在锦标赛上进行操作然后扔掉时予以实例化。
public class TournamentController { @Autowired private TournamentDAO tournamentDAO; private final Tournament tournament; public TournamentController( Tournament tournament ) { this.tournament = tournament; } public void startTournament() { if ( tournament.getState() != TournamentState.SETUP ) { throw new TournamentAlreadyStartedException(); } tournament.setState( TournamentState.IN_PROGRESS ); //... some other logic and calls to other DAOs tournamentDAO.save( tournament ); } }
我还创建了一个TournamentResource类,它是比赛的REST前端。它的责任是进行一些基本的验证(用户安全…)和异常转换。
@Path( "/tournament" ) @Component @Scope( "prototype" ) public class TournamentResource { private static final Log log = LogFactory.getLog( TournamentResource.class ); @Autowired private TournamentDAO tournamentDAO; @GET @Path( "{tournamentId}/start" ) @Produces( MediaType.APPLICATION_JSON ) @Transactional public TournamentDTO startTournament( @PathParam( "tournamentId" ) long tournamentId ) { Tournament tournament = tournamentDAO.getTournament( tournamentId, LockMode.PESSIMISTIC_WRITE ); if ( tournament == null ) { throw new WebApplicationException( Status.NOT_FOUND ); } try { TournamentController controller = new TournamentController( tournament ); controller.startTournament(); } catch ( TournamentAlreadyStartedException e ) { log.warn( "Could not start tournament " + tournamentId + " since it is already started." ); throw new RestException( Status.BAD_REQUEST, "Tournament already started" ); } return DTOConverterUtil.getTournament( tournament ); } }
我正在使用AspectJ进行加载时间编织。这是我的上下文:
<context:annotation-config /> <!-- Make spring aware ANY pojo with the @Configurable annotation --> <context:spring-configured /> <!-- Scan all classes in com.mdarveau for annotations --> <context:component-scan base-package="so.question" /> <!-- Load Time Weaver --> <context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" aspectj-weaving="on" /> <!-- DB config --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> ... </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="com.mdarveau.fnp.model" /> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect </value> </property> </bean> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- enable @Transactional --> <tx:annotation-driven transaction-manager="txManager" mode="aspectj" />
我的TournamentResource课程是按设计的单例课程,并且运行良好。
我的问题是,当实例化TournamentControllerusing new而不是spring时,它的@Autowired属性似乎未正确连接。我尝试在其上添加@Component注释,但未成功。
我应该制作TournamentResource ApplicationContextAware并创建TournamentController贯穿弹簧吗?
这一定是一个相当普遍的问题。我看到了很多示例,其中后端是单例,但我想避免将传递Tournament给每个方法调用TournamentController(然后传递给中的所有私有方法TournamentController)。