j2EE,框架采用struts2,spring,hibernate,服务器端处理请求的顺序是action > service > dao .
因为所有对象的service都有增删改查操作,所以我们使用一个基类,然后所有的service类都继承这个基类,这个service基类的代码如下:
public class BaseServiceImpl<T, E> {
//the class of the bean's dao .
public T dao ;
//save object
public boolean set( E obj ) {
if ( dao==null ) return false; //@1
if ( obj==null ) return true;
try {
Class clazz = dao.getClass();
Method method = clazz.getMethod( "save" , obj.getClass() ); //@2
//clazz.getDeclaredMethod(name, parameterTypes)
boolean R = (Boolean) method.invoke( dao , (Object) obj );
return R;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
下面给出service类的代码,他继承自 BaseServiceImpl :
@Component("abnormalListManage")
public class FreightCenter_abnormalListManageImpl <E> extends BaseServiceImpl<FreightCenter_abnormalListDao,FreightCenter_abnormalList> implements FreightCenter_abnormalListManage,reflectData {
@Resource(name="abnormalListDao")
private FreightCenter_abnormalListDao listDao;
public FreightCenter_abnormalListManageImpl() {
super.dao = listDao;
}
}
**同样的dao类也有基类,然后每个dao类都继承自这个基类
dao基类的代码如下:**
public class BaseDaoImpl<T, E> {
//SessionFactory for create session
public SessionFactory sessionFactory = null;
//the class of the bean's manage
public T manage = null;
public boolean save( E obj ) {
//do sth.
}
}
dao类代码如下:
@Transactional
@Component("abnormalListDao")
public class FreightCenter_abnormalListDaoImpl extends BaseDaoImpl<FreightCenter_abnormalListManage, FreightCenter_abnormalList> implements FreightCenter_abnormalListDao{
@Resource
private SessionFactory sessionFactory;
@Resource( name="abnormalListManage" )
private FreightCenter_abnormalListManage abnormalListManage;
public FreightCenter_abnormalListDaoImpl() {
super.sessionFactory = sessionFactory;
super.manage = abnormalListManage;
}
}
现在问题来了,当我们执行service类的set方法时,set方法里面的语句:
if ( dao==null ) return false; //在 service 基类 BaseServiceImpl 里面,标注为@1
在这个语句中,成员变量 dao 是 null 值,个人分析如下:
service类 FreightCenter_abnormalListManageImpl 是由spring来管理,他是在服务器运行时初始化的
初始化这个类时运行了构造方法,构造方法中将ListDao传递给基类的变量 dao ,但是这个时候 ,listDao肯定是null,因为spring肯定是在类初始化完成后才给ListDao赋值!
为了解决这个问题,我们在service类里面重写了set方法
修改后,service类的实现类代码如下:
@Component("abnormalListManage")
public class FreightCenter_abnormalListManageImpl <E> extends BaseServiceImpl<FreightCenter_abnormalListDao,FreightCenter_abnormalList> implements FreightCenter_abnormalListManage,reflectData {
@Resource(name="abnormalListDao")
private FreightCenter_abnormalListDao listDao;
public FreightCenter_abnormalListManageImpl() {
super.dao = listDao;
}
public boolean set( FreightCenter_abnormalList obj ) { //重写set方法
super.dao = listDao;
return super.set( obj );
}
}
这样就解决了上面的问题 .
但是,另外的问题出现了,当执行到语句( 使用@2来标注 ):
Method method = clazz.getMethod( "save" , obj.getClass() );
boolean R = (Boolean) method.invoke( dao , (Object) obj );*
时报错,save方法不存在!
我现在的问题是:
1 在service类里面,如果我不重写set方法,如何将变量listDao的值传递给service基类?我希望是在service类初始化之后传递,如何解决?如果可以,我就不用重写那么多方法了,因为我还有好多方法需要重写.
2 为什么反射调用dao类的save方法时会报错?难道继承自基类(父类)的方法不属于本类的方法?
First question
The key to the problem is here:
Because it is constructed in the method,
listDao
has not been assigned a value, sosuper.dao
must benull
. But looking through the code, I can't find where you assign a value tolistDao
. You just need to assign a value tolistDao
synchronously when assigning a value tosuper.dao
. Generally speaking, you should have asetListDao()
method, you just need to change this methodSecond question
Quoting @wanlion’s own answer (put here for easy reading)
should be changed to:
Improvements regarding the second question
As far as the current code is concerned, you only need to add an interface to avoid reflection
is not added.