1.抽象类不能实例化
最近在搭建SSH框架的时候,我在封层底层的DAO【BaseDao.java】层时,有个方法不能再BaseDao具体实现,为了防止后面的的人,继承该基本类的人,不会忽略重载该类,我便将其写成抽象类,因此,BaseDao类也必须为抽象类
@Repository
public abstract class BaseDao extends HibernateDao {
/**
* 获得实体的组合条件
* @return
*/
public abstract Criterion[] criterionsArray(T entity);
...
}
然而我有写了一个基本的Service类【BaseService】,为了减少应用层,重复再应用层写增删改查的函数,我就干脆在BaseSerice将其实现:
@Service
@Transactional
public abstract class BaseService {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private BaseDao baseDao;
public void create(T entity) {
baseDao.create(entity);
}
public void delete(T entity) {
baseDao.delete(entity);
}
public void update(T entity) {
baseDao.update(entity);
}
public List list(T entity){
Assert.assertNotNull(entity);
return baseDao.list(entity);
}
public T get(String id){
return (T) baseDao.get(id);
}
...
}
问题来了,我在Junit测试框架中,应用层【UserSerivice extends BaseService】:测试结果
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.cqs.common.base.dao.BaseDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
自动装配错误。网上说因为各层没有写注解(就是action层添加@Action,service层添加@Service,@Transactional及dao层添加@Repository),我按此方法检查了所有的类,发现都写了【PS之前碰到过,有个service层的类没有写@service注解,的确抛了上述异常】.
为了缩小访问,我有在Junit中,写了一个BaseDao的测试,只做一件事,自动装配BaseDao
public class HibernateDaoTest extends BaseTestConfig{
@Autowired
private BaseDao baseDao;
@Test
public void testGetCurrentSession(){
System.out.println("==");
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:applicationContext.xml"})
@Transactional
public class BaseTestConfig extends AbstractJUnit4SpringContextTests {
protected static Logger logger = LoggerFactory.getLogger(BaseTestConfig.class);
}
运行结果,抛出异常:
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.cqs.common.base.dao.BaseDao] is defined: expected single matching bean but found 2: imageUploadDao,userDao
很好,这说明实例化了两个继承BaseDao的类,而BaseDao却不能实例化。所以原因就是在BaseService实例化的BaseDao,却BaseDao却是抽象类,而抽象类是不能实例化的!
下面就是修改BaseDao成普通类就行了
@Repository
public class BaseDao extends HibernateDao {
/**
* 获得实体的组合条件
* @return
*/
public Criterion[] criterionsArray(T entity){
return null;
};
....
}
但是问题就是,结构不如之前申明抽象类好了[后面继承BaseDao类,在没有提示的情况下,重载criterionsArray方法],但是,后面一种办法,可以避免写好些重复性质的代码。