3.Sprint 代理对象与原始对象的异常错误
代码案例分析
- Service层添加了注解@Transactional
@Service @Transactional public class CustomerService extends BaseService<CustomerModel, CustomerQueryModel> implements ICustomerService { private CustomerDAO dao = null; @Autowired public void setDao(CustomerDAO dao) { this.dao = dao; super.setDao(dao); } }
- Client端同时也增加了注解@Transactional
@Service @Transactional public class Client { @Autowired private ICustomerService s = null; public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); Client t = (Client)ctx.getBean("client"); // CustomerModel cm = new CustomerModel(); // cm.setCustomerId("c1"); // cm.setPwd("c1"); // cm.setRegisterTime(""); // cm.setShowName("c1"); // cm.setTrueName("王五"); // // t.dao.create(cm); CustomerQueryModel cqm = new CustomerQueryModel(); cqm.getPage().setNowPage(1); Page<CustomerModel> p = t.s.getByConditionPage(cqm); System.out.println("p=="+p); } }
- 异常空指针错误信息
Exception in thread "main" java.lang.NullPointerException
at com.sishuok.architecture1.customermgr.Client.main(Client.java:38)
Client.java:38行报的异常错误信息,就是Page<CustomerModel> p = t.s.getByConditionPage(cqm);
经过分析,t对象肯定存在,只有s对象存在空指针,为什么呢?
原因是因为增加了@Transactional 之后,又被代理了一次,意思就是sprint的原始对象与代理对象的问题,s的原始对象是有的,但是t.s拿到的是@Transactional 代理过后的对象,t.s 和s 不是同一个对象,解决办法如下
@Service @Transactional public class Client { @Autowired private ICustomerService s = null; public ICustomerService getS() { return s; } public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); Client t = (Client)ctx.getBean("client"); // CustomerModel cm = new CustomerModel(); // cm.setCustomerId("c1"); // cm.setPwd("c1"); // cm.setRegisterTime(""); // cm.setShowName("c1"); // cm.setTrueName("王五"); // // t.dao.create(cm); CustomerQueryModel cqm = new CustomerQueryModel(); cqm.getPage().setNowPage(1); // Page<CustomerModel> p = t.s.getByConditionPage(cqm); Page<CustomerModel> p = t.getS().getByConditionPage(cqm); System.out.println("p=="+p); }
一切正常,为什么可以解决?代理的时候通过方法进行访问(拦截的方法),属性的就没有正常的代理private ICustomerService s = null;