问题描述
- 一个Spring4Hibernate4的开源项目,spring注解了接口,这是什么意思?
-
//Service
@Service
@Transactional
public class UserLogonLogService extends BaseService {
@Autowired
private UserLogonLogDao userLogonLogDao;... //Dao @Repository
public interface UserLogonLogDao extends BaseDao {
看着UserLogonLogDao是个接口,就没有找到关于这个接口的实现代码,那他怎么运作呢?
来源:https://github.com/xautlx/s2jh4net/blob/master/src/main/webapp/docs/markdown/%E5%BC%80%E5%8F%91%E9%85%8D%E7%BD%AE.md
解决方案
解决方案二:
既然有自动注入,而这个接口又是你自定义的,当然是有实现类的。在这个接口文件中,选中这个接口名称后按Ctrl+T查看这个类型层次结构图,就能知道有哪些实现类了。
解决方案三:
既然是接口那就肯定有实现它的地方.
你看看自己配制的Bean的XML中有没有定义
如果没有你就用userLogonLogDao进行全局检索,都有哪些地方用了
比如动态创建对象的反射代码
或者是哪里配置了代理的对象
。。。
肯定有它对应的实现类对象的
解决方案四:
package lab.s2jh.aud.dao;
@Repository
public interface UserLogonLogDao extends BaseDao {
UserLogonLog findByHttpSessionId(String httpSessionId);
}
这个接口定义了注解:org.springframework.stereotype.Repository;
BaseDao继承自org.springframework.data.jpa.repository.JpaRepository;
实际用到了spring jpa,spring启动扫描包时,会根据注解,产生一个这个接口的代理类,
代理类最基础的工作就是根据泛型参数,让持久层用主键(Long)操作类对象UserLogonLog,
你可以看一下UserLogonLog这个类的实现代码
lab.s2jh.aud.entity.UserLogonLog extends PersistableEntity{
@Id
@GeneratedValue(generator = "idGenerator")
@GenericGenerator(name = "idGenerator", strategy = "native")
private Long id;
@MetaData(value = "Session编号")
@Column(length = 128, nullable = false, unique = true)
private String httpSessionId;
...
这里定义了实体类Entity的详细信息,最后在这个类里,就可以直接通过spring注入userLogonLogDao
package lab.s2jh.aud.service;
@Service
@Transactional
public class UserLogonLogService extends BaseService {
@Autowired
private UserLogonLogDao userLogonLogDao;
简单的说entity.UserLogonLog定义了所有字段,以及主键这类特殊信息,
UserLogonLogDao extends BaseDao
通过父接口JpaRepository,spring jpa也就知道了如何操作entity.UserLogonLog,
包括更新这个对象,保存这个对象,删除这个对象,以及查找这个对象.
findByHttpSessionId方法也将会自动实现,因为很清楚就是在所有对象中查找指定httpSessionId的.
当然最终的代码实际是hibernate完成的.
spring-jpa.xml中
<!-- Spring Data JPA配置 -->
entity-manager-factory-ref="entityManagerFactory">
/jpa:repositories
这里引用了entityManagerFactory,其定义在
<!-- JPA Entity Manager 配置, 设置depends-on="cacheManager",确保共享模式下优先加载Spring CacheManager -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
depends-on="cacheManager">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="entityManager" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${jpa_database_platform}" />
</bean>
</property>
<property name="packagesToScan">
<list>
<value>lab.s2jh.core.audit.envers</value>
<value>lab.s2jh.**.entity</value>
<value>s2jh.biz.**.entity</value>
</list>
</property>
...
所以不再需要你自己实现任何代码了.
解决方案五:
其实mybatis的注解方式,理解起来要简单得多,jpa也是类似只是自动完成更多.
比如一个接口,只要用org.apache.ibatis.annotations.Select 注解了方法
IUsr{
/**消费操作,修改主表余额*/
@Select("select * from usrlist where uid=#{uid}")
public List> getList(int uid);
}
mybatis扫描时,就会自动建立一个代理类,方法getlist你自己都可以猜出来,就是执行注解里的select语句,将返回的结果放到一个list里
这些代码,mybatis的代理类会自动完成.
然后你可以随意将这个代理类注入到其它类
@Autowired
private IUsr adao;
spring会查找到实现Iusr的mybatis的代理类,并将它自动注入
你就可以直接用 adao.getList(1)了.