При использовании аннотации @Transactional Spring создает JDK-прокси, когда класс реализует интерфейс. В вашем случае JDK-прокси (UserDao реализует Dao ) будет реализовывать Dao , но не будет расширять UserDao. Следовательно, bean-компонент в контексте будет Dao .
Если класс с аннотацией @Transaction не реализует интерфейс, Spring должен создать прокси-сервер CGLIB, расширяющий UserDao. Следовательно, bean-компонент в контексте будет UserDao.
Вы можете указать Spring всегда использовать прокси-серверы CGLIB, когда помещаете это в applicationContext.xml:
<tx:annotation-driven transaction-manager="trx-manager" proxy-target-class="true" />
Есть некоторые недостатки, но я их не помню.
Я не использую proxy-target-class = "true", и мой дизайн такой:
У меня есть интерфейс для каждого типа Дао.
public interface UserDao extends Dao<User>
List<User> findByUsername();
Я реализую определенный интерфейс
@Component
public class UserDaoJpa implements UserDao
public List<User> findByUsername() {
...
}
Мои классы обслуживания используют UserDao:
public class UserService {
@Autowired
private UserDao userDao;
}
Бин в контексте - это UserDaoJpa, и он будет внедрен, когда используется UserDao.