论坛首页 Java企业应用论坛

遇到一个设计上的问题,请问如何解决?

浏览 16636 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (2)
作者 正文
   发表时间:2008-06-18  
举个例子来说:例如有n多个业务类接口及其实现:teacherManager,studentManager.....
我以前这样用,如果teacherManager需要studentManager的方法,就会在teacherManager添加一个studentManager。然后注入:
<bean id="teacherManager" class="test.teacherManagerImpl">
<property name="studentManager" ref="studentManager" />
</bean>

现在我想用一个类来统一管理这些业务类。
<bean id="teacherManager" class="test.teacherManagerImpl">
<property name="app" ref="app" />
</bean>

<bean id="app" class="test.appImpl">
<property name="teacherManager" ref="teacherManager" />
<property name="studentManager" ref="studentManager" />
</bean>

但是在启动tomcat的时候,报错。原因是在初始化teacherManagerImpl时,需要初始化app,
而初始化app,需要初始化teacherManagerImpl。就像进入死循环一样。

请问appImpl应该如何初始化那些业务类呢?好像用spring的注入无法实现。
   发表时间:2008-06-18  
引用
如果teacherManager需要studentManager的方法,就会在teacherManager添加一个studentManager

就说明这个方法不能放到studentManager里面。
0 请登录后投票
   发表时间:2008-06-18  
你用autowire=byName就可以实现自动注入,没必要显示写property
0 请登录后投票
   发表时间:2008-06-18  

方法1:让你的AppImpl感知Spring的存在,直接从Spring中获取。

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class AppImpl implements ApplicationContextAware {

	private ApplicationContext applicationContext;
	private StudentService studentService;
	private TeacherService teacherService;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public StudentService getStudentService() {
		if (null == studentService) {
			studentService = (StudentService) applicationContext
					.getBean("studentService");
		}// if
		return studentService;
	}

	public TeacherService getTeacherService() {
		if (null == teacherService) {
			teacherService = (TeacherService) applicationContext
					.getBean("teacherService");
		}// if
		return teacherService;
	}

}
 

 

方法2:实现Applicationable接口

public interface Applicationable {

	void setApplication(Application application);
	
	Application getApplication();
	
}

 StudentService与TeacherService接口都extends这个Applicationable

//StudentService.java
public interface StudentService extends Applicationable {

}


//TeacherService.java
public interface TeacherService extends Applicationable {

}

 然后在AppImpl类中注入StudentService与TeacherService的时候做手脚

public class AppImpl implements Application {

	private StudentService studentService;
	private TeacherService teacherService;

	public StudentService getStudentService() {
		return studentService;
	}

	public void setStudentService(StudentService studentService) {
		studentService.setApplication(this);
		this.studentService = studentService;
	}

	public TeacherService getTeacherService() {
		return teacherService;
	}

	public void setTeacherService(TeacherService teacherService) {
		teacherService.setApplication(this);
		this.teacherService = teacherService;
	}

}

 

 

不过真的有必要这样做么...我个人还是倾向于如果StudentService中要用到TeacherService,那么我就直接在StudentService中注入好了,用autowire来辅助你完成注入,可以让你省略到一大堆的

<property name="studentManager" ref="studentManager" />
 
0 请登录后投票
   发表时间:2008-06-18  
test.appImpl定义一个初始化方法或者使用Spring的InitalizingBean接口。
在初始化方法(或者InitalizingBean的afterPropertiesSet方法)里面加一行;

teacherManager.setApp(this);

去掉spring 配置teacherManager里面的propety

<bean id="teacherManager" class="test.teacherManagerImpl">  
<!--<property name="app" ref="app" /> --> 
</bean>
 

这是个没办法的办法,最好不要写这样的互相注入的设计。架构没搞好。
    
0 请登录后投票
   发表时间:2008-06-18  
我只是看了roller这样来调用业务类的,但是他不是用的spring,而是用google inject。
0 请登录后投票
   发表时间:2008-06-18  
agapple 写道
你用autowire=byName就可以实现自动注入,没必要显示写property


我看过一些文章,说是避免使用。
0 请登录后投票
   发表时间:2008-06-18  
还是不要出现这样互相注入的好。
5 请登录后投票
   发表时间:2008-06-19  
volking 写道
举个例子来说:例如有n多个业务类接口及其实现:teacherManager,studentManager.....
我以前这样用,如果teacherManager需要studentManager的方法,就会在teacherManager添加一个studentManager。然后注入:
<bean id="teacherManager" class="test.teacherManagerImpl">
<property name="studentManager" ref="studentManager" />
</bean>

现在我想用一个类来统一管理这些业务类。
<bean id="teacherManager" class="test.teacherManagerImpl">
<property name="app" ref="app" />
</bean>

<bean id="app" class="test.appImpl">
<property name="teacherManager" ref="teacherManager" />
<property name="studentManager" ref="studentManager" />
</bean>

但是在启动tomcat的时候,报错。原因是在初始化teacherManagerImpl时,需要初始化app,
而初始化app,需要初始化teacherManagerImpl。就像进入死循环一样。

请问appImpl应该如何初始化那些业务类呢?好像用spring的注入无法实现。


第一,循环依赖应该避免
第二,个人觉得“用一个类来统一管理这些业务类”毫无意义,因为这是Spring的工作
0 请登录后投票
   发表时间:2008-06-19  
楼主是想实现一个service facotry类么?试试设置bean的<factory-bean>和<factory-method>属性
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics