Dao tier. I have abstract jpa dao interface, extended interface, and I added abstract implementation, from which I extend other real used implementations. These classes as follows:
public interface AbstractDao<E> { E findById(Long id); List<E> findAll(); void save(E entity); void update(E entity); void delete(E entity); void deleteById(Long entityId); }
public interface UserDao extends AbstractDao<User> { }
public abstract class AbstractDaoImpl<E> implements AbstractDao<E> { private final Class<E> clazz; @PersistenceContext protected EntityManager entityManager; public AbstractDaoImpl(Class<E> clazz) { this.clazz = clazz; } @Override public E findById(Long id) { return entityManager.find(clazz, id); } @SuppressWarnings("unchecked") @Override public List<E> findAll() { return entityManager .createQuery("from " + clazz.getName()) .getResultList(); } @Override public void save(E entity){ entityManager.persist(entity); } @Override public void update(E entity){ entityManager.merge(entity); } @Override public void delete(E entity) { entityManager.remove(entity); } @Override public void deleteById(Long entityId){ E entity = findById(entityId); delete(entity); } }
@Repository public class UserDaoImpl extends AbstractDaoImpl<User> implements UserDao { public UserDaoImpl() { super(User.class); } }
Service tier. Here I also have abstract service interface, one extended interface (UserService) and its abstract and real implementations:
public interface AbstractService<E, DTO> { E findById(Long id); List<E> findAll(); void save(E entity); void update(E entity); void delete(E entity); void deleteById(Long entityId); DTO convertToDTO(E entity); }
public interface UserService extends AbstractService<User, UserDTO> { }
@Getter @Setter @AllArgsConstructor public abstract class AbstractServiceImpl<E, D extends AbstractDao<E>, DTO> implements AbstractService<E, DTO> { private D dao; private ModelMapper mapper; @Override public E findById(Long id) { return dao.findById(id); } @Override public List<E> findAll() { return dao.findAll(); } @Override public void save(E entity) { dao.save(entity); } @Override public void update(E entity) { dao.update(entity); } @Override public void delete(E entity) { dao.delete(entity); } @Override public void deleteById(Long entityId) { dao.deleteById(entityId); } }
@Service public class UserServiceImpl extends AbstractServiceImpl<User, UserDao, UserDTO> implements UserService { @Autowired public UserServiceImpl(UserDao dao, ModelMapper mapper) { super(dao, mapper); } @Override public UserDTO convertToDTO(User entity) { return getMapper().map(entity, UserDTO.class); } }
In my real project I got many extended interfaces from AbstractDao and AbstractServie. You can see the actual hierarchy:
I can’t understand why spring can’t create @Service annotated beans and autowire those in my Controllers. Any help would be appreciated.
Advertisement
Answer
I took the liberty to look into your project in github https://github.com/tuanalexeu/JavaSchoolFinalTask
The problem is how you initialize your spring contexts, The AppConfig context is not read at all. This context has all your configurations.
By modifying your initializer to include your AppConfig as root, all beans should be present in the same context. (You can also choose to have parent -> child contexts as well, but that too should be done in the initializer). Hope it helps. Good luck.
public class MainWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(final ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.register(AppConfig.class); Dynamic servlet = sc.addServlet("dispatcher", new DispatcherServlet(root)); servlet.setLoadOnStartup(1); servlet.addMapping("/"); sc.addListener(new ContextLoaderListener(root)); sc.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain")) .addMappingForUrlPatterns(null, false, "/*"); } }