这有点长,但我只是想用spring 4.1.7来学习花哨的东西
我面临的问题是Spring并不喜欢在Reader和Writer控制器中没有为R和W声明bean。一切都编译但在运行时没有任何作用,我得到错误
Error creating bean with name 'userController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected carefree.coding.dao.CommerceReaderDAO carefree.coding.controllers.rest.CommerceReaderController.reader; nested exception is java.lang.IllegalArgumentException: Can not set carefree.coding.dao.CommerceReaderDAO field carefree.coding.controllers.rest.CommerceReaderController.reader to com.sun.proxy.$Proxy57
我有一个简单的DAO类
@MappedSuperclass
public abstract class CommerceObject
{
public enum Type
{
USER
}
@Transient
protected Type type;
@Id
@GeneratedValue
@Column(name = "id")
protected long id;
public CommerceObject(Type type)
{
this.type = type;
setId(-1l);
}
public Type getType()
{
return type;
}
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public boolean equals(CommerceObject object)
{
return getId() == object.getId() && getType().equals(object.getType());
}
@Override
public String toString()
{
return new Gson().toJson(this);
}
public CommerceObject fromString(String json)
{
return new Gson().fromJson(json, getClass());
}
public abstract boolean update(CommerceObject object);
public abstract CommerceObject copy();
@Override
public int hashCode()
{
throw new UnsupportedOperationException("No hashing for game objects");
}
}
由
扩展@Entity(name = "user")
public class User extends CommerceObject
{
@Column(name = "email")
private String email;
public User()
{
super(Type.USER);
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
@Override
public boolean update(CommerceObject object)
{
if (object instanceof User)
{
User user = (User) object;
if (equals(user))
{
user.setEmail(email);
}
}
return false;
}
@Override
public CommerceObject copy()
{
User user = new User();
user.setEmail(getEmail());
return user;
}
}
为了读取和写入数据库,我有两个接口
阅读器
public interface CommerceReaderInterface<V extends CommerceObject>
{
@Transactional(readOnly = true)
List<V> get();
@Transactional(readOnly = true)
V get(long id);
}
作家
public interface CommerceWriterInterface<V extends CommerceObject>
{
@Transactional
V add(V v);
@Transactional
V update(V v);
@Transactional
V delete(V v);
}
基本数据库访问类
public abstract class CommerceDAO
{
protected SessionFactory sessionFactory;
protected Class aClass;
public CommerceDAO(SessionFactory sessionFactory, Class aClass)
{
this.sessionFactory = sessionFactory;
this.aClass = aClass;
}
}
允许读者和作者存在
阅读器
public class CommerceReaderDAO<V extends CommerceObject> extends CommerceDAO implements CommerceReaderInterface<V>
{
public CommerceReaderDAO(SessionFactory sessionFactory, Class aClass)
{
super(sessionFactory, aClass);
}
@Override
public List<V> get()
{
ClassMetadata hibernateMetadata = sessionFactory.getClassMetadata(aClass);
if (hibernateMetadata == null)
{
return null;
}
if (hibernateMetadata instanceof AbstractEntityPersister)
{
AbstractEntityPersister persister = (AbstractEntityPersister) hibernateMetadata;
String tableName = persister.getTableName();
if (tableName != null)
{
return sessionFactory.getCurrentSession().
createQuery(tableName).list();
}
}
return null;
}
@Override
public V get(long id)
{
V object = (V) sessionFactory.getCurrentSession().
get(aClass, id);
Hibernate.initialize(object);
return object;
}
}
作家
public class CommerceWriterDAO<V extends CommerceObject> extends CommerceDAO implements CommerceWriterInterface<V>
{
public CommerceWriterDAO(SessionFactory sessionFactory, Class aClass)
{
super(sessionFactory, aClass);
}
@Override
public V add(V v)
{
if (v != null)
{
sessionFactory.getCurrentSession().save(v);
return v;
}
return null;
}
@Override
public V update(V v)
{
if (v != null)
{
sessionFactory.getCurrentSession().update(v);
return v;
}
return null;
}
@Override
public V delete(V v)
{
if (v != null)
{
sessionFactory.getCurrentSession().delete(v);
sessionFactory.getCurrentSession().flush();
return v;
}
return null;
}
}
对于控制器,我决定做同样的事情,并有一个读写器界面
阅读器
public interface CommerceReaderInterface
{
@RequestMapping(value = "/get",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> get();
@RequestMapping(value = "/get/{id}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> get(@PathVariable long id);
}
作家
public interface CommerceWriterInterface<V extends CommerceObject>
{
@RequestMapping(value = "/add",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> add(@RequestBody V v);
@RequestMapping(value = "/update",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> update(@RequestBody V v);
@RequestMapping(value = "/delete",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> delete(@RequestBody V v);
}
它们正常实施
阅读器
public abstract class CommerceReaderController<R extends CommerceReaderDAO<V>, V extends CommerceObject> implements CommerceReaderInterface
{
@Autowired
protected R reader;
@Override
public ResponseEntity<String> get()
{
List<V> list = reader.get();
if (list == null || list.isEmpty())
{
return ResponseUtil.notFound();
}
return ResponseUtil.ok(list);
}
@Override
public ResponseEntity<String> get(@PathVariable long id)
{
V object = reader.get(id);
if (object == null)
{
return ResponseUtil.notFound();
}
return ResponseUtil.ok(object);
}
}
作家
public abstract class CommerceWriterController<W extends CommerceWriterDAO<V>, R extends CommerceReaderDAO<V>, V extends CommerceObject> extends CommerceReaderController<R, V> implements CommerceWriterInterface<V>
{
@Autowired
protected W writer;
@Override
public ResponseEntity<String> add(@RequestBody V v)
{
v = writer.add(v);
if (v == null)
{
return ResponseUtil.notFound();
}
return ResponseUtil.ok(v);
}
@Override
public ResponseEntity<String> update(@RequestBody V v)
{
v = writer.update(v);
if (v == null)
{
return ResponseUtil.notFound();
}
return ResponseUtil.ok(v);
}
@Override
public ResponseEntity<String> delete(@RequestBody V v)
{
v = writer.delete(v);
if (v == null)
{
return ResponseUtil.notFound();
}
return ResponseUtil.ok(v);
}
}
在完成所有这些工作后,我认为允许使用简单的控制器
@Controller
@RequestMapping("/commerce/api/user")
public class UserController extends CommerceWriterController<UserWriterDAO, UserReaderDAO, User>
{
}
然而,正如我在抽象控制器中所理解的那样,我不允许有这样模糊的DAO对象。有什么办法可以绕过这个吗?