1.抽象类不能实例化
最近在搭建SSH框架的时候,我在封层底层的DAO【BaseDao.java】层时,有个方法不能再BaseDao具体实现,为了防止后面的的人,继承该基本类的人,不会忽略重载该类,我便将其写成抽象类,因此,BaseDao类也必须为抽象类
@Repository public abstract class BaseDao<T, PK extends Serializable> extends HibernateDao { /** * 获得实体的组合条件 * @return */ public abstract Criterion[] criterionsArray(T entity); ... }
然而我有写了一个基本的Service类【BaseService】,为了减少应用层,重复再应用层写增删改查的函数,我就干脆在BaseSerice将其实现:
@Service @Transactional public abstract class BaseService<T, PK extends Serializable> { protected Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private BaseDao<T, Serializable> 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<T> 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<T, PK extends Serializable> extends HibernateDao { /** * 获得实体的组合条件 * @return */ public Criterion[] criterionsArray(T entity){ return null; }; .... }
但是问题就是,结构不如之前申明抽象类好了[后面继承BaseDao类,在没有提示的情况下,重载criterionsArray方法],但是,后面一种办法,可以避免写好些重复性质的代码。