Spring autowire trouble with generic parameter

别等时光非礼了梦想. 提交于 2019-12-13 03:41:18

问题


I try to use generic parameter in autowire but it doesn't work. My goal is to create a generic JSON controller with Spring 4.1.3 and Hibernate

I have a generic abstract class , and I use it to create service via a model objec(the same as my DAO) as generic parameter.

The code of my AbstractService

public interface IGenericService<T extends Serializable> extends IOperations <T>{}

public interface IOperations<T extends Serializable> {
    T findOne(final long id);
    List<T> findAll();
    void create(final T entity);
    T update(final T entity);
    void delete(final T entity);
    void deleteById(final long entityId);
    List<T> findByField(String field, String value);
    T save(final T entity);
}

//MyAbstractService (generic service)                        
public abstract class AbstractService<T extends Serializable> implements
        IGenericService<T> {

    public static final Logger logger = LoggerFactory
            .getLogger(AbstractService.class);

    public AbstractService(){}

   ...
    @Override
    @Transactional
    public T update( T entity) {

        logger.debug("public T update( T entity)");
        return getDao().update(entity);
    }
...
}

Now I create a SecuredUserService with this abstract service

@Transactional
@Component //(value = "userService")
@Qualifier("userService")
public class UserService extends AbstractService<SecuredUser> implements
        IUserService {
 // I override the method upate of the abstract service
@Override
@Transactional
public SecuredUser update(SecuredUser user){
... // password encoding for example
}
}
public interface IUserService extends IGenericService<SecuredUser> {
     T findOne(final long id);
    ...
    }

In my JUnit test I made autowire with this code :

@Autowire
IGenericService<SecuredUser> userGenericService;

Or

@Autowire
IUserService userService;

At this point every thing is ok, I use the overrided method of userService and not those of abstractService. I pass my Junit Test. An I create a package.

Now I want to make generic spring mvc controller to handle common Json request GET/PUT/DELETE/POST :

//Generic Controller

public abstract class GenericSecuredController  <MODEL     extends Serializable> extends CommonSecuredController {

    /**
     * spring generic service retrieve by MODEL class type
     */
    @Autowired
    private IGenericService <MODEL> genericService;
    /**
     * Spring generic URI retrieve by MODEL class type
     */
    @Autowired
    private IGenericURI<MODEL> genericURI ;
...
}

// interface to manage URI in a generic way

public interface IGenericURI<MODEL extends Serializable> {

    // root for the controller
    public static String CONTROLLER_MAPPING="" ;
    // path to the file system
    public static String PATH_MAPPING = "";
    // key to retrieve data in path
    public static  String PATH="{id}";
    // Json REST SERVICE MappedUri
    public static  String JSON_DUMMY = "/dummy";
    public static  String JSON_GET = "/" + PATH;
    public static  String JSON_GET_ALL = "";
    public static  String JSON_CREATE = "";
    public static  String JSON_DELETE = "/" + PATH;
    public static  String JSON_UPDATE = "/" + PATH;

    public static String HTML_VIEW = "/{view}.view.html";
    public String getControllerMapping() ;
    public String getPathMapping() ;

}

// The specific URI for the SecuredUser model object

@Component
public  class SecuredUserURI implements Serializable, IGenericURI<SecuredUser> {
    public static final String CONTROLLER_MAPPING = "/user";
    public static final String PATH_MAPPING = "user";

    public String getControllerMapping() {
        return CONTROLLER_MAPPING;
    }

    public String getPathMapping() {
        return PATH_MAPPING;
    }
}                      

Now I could create a specific controller for SecuredUser like this :

public class UserController extends GenericSecuredController<SecuredUser> {
    /**
     * creator to set Class type for the GenericSecuredController<MODEL>
     */
    public UserController() {
        super(SecuredUser.class);
    }
 }

The problem appear at this point. The autowire of the

IGenericURI<MODEL> 

work fine, but the autowiring with

IGenericService <MODEL> genericService; 

doesn't use the overrided specific method of the userService but the abstract method with common behaviour!!!

So my question is : Is it possible to autowire bean with generic parameter like in my example. Maybe there is to many level for Spring autowiring .

Other information : As workaround, I try to pass the userService as parameter of the contoller but, the same behaviour: the generic service use the abstract method.

UPDATE : If I autowire IGenericService genericService in the UserController and create a new handler, the specific service is call.

Thanks

来源:https://stackoverflow.com/questions/28246197/spring-autowire-trouble-with-generic-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!