to everybody click my question, thank you(my eng is bad).
The spring version Im working on is 3.2.9. And it's been used Field Injection like
@Controller
@RequestMapping("/test/something")
public class TestController {
@Autowired
private TestService testService;
}
But Recently, I knew Using the Constructor Injection is way safey and better than Field Injection and Setter Injection.
So I've been trying to use Constructor Injection but it doesnt work.
I tried this
@Controller
@RequestMapping("/test/something")
public class TestController {
private final TestService testService;
@Autowired
public TestController (TestService testService){
this.testService = testService;
}
}
The console keeps throwing up bunch of error.
Which is BeanCreationException(Error creating bean with name...), AopConfigException(could not generate CGLIB...), IllegalArgumentException(Super class has no null constructor but no arguments were given).
Also, I've been trying to take off the 'final' and '@Autowired'. It's same. Doesnt work.
1.
@Controller
@RequestMapping("/test/something")
public class TestController {
@Autowired
private TestService testService;
@RequestMapping(value="/happy.do")
public ModelAndView happything(){
ModelAndView mav = new ModelAndView();
List<HashMap<String, Object>> happyListMap = testService.getHappyList();
mav.addObject("happyListMap", happyListMap);
mav.setViewName("world/happy/list");
return mav;
}
}
2.
public interface TestService {
List<HashMap<String, Object>> getHappyList();
}
3.
@Service("TestService")
public class TestServiceImpl implements TestService {
@Autowired
private TestMapper testMapper;
@Autowired
private HelpMapper helpMapper;
@Override
public List<HashMap<String, Object>> getHappyList(){
int happyPoint = helpMapper.selectHowMuchHappyYouAre();
List<HashMap<String, Object>> happyListMap = testMapper.selectHappyList(happyPoint);
return happyListMap;
}
}
4.
@Mapper("TestMapper")
public interface TestMapper {
List<HashMap<String, Object>> selectHappyList(int happyPoint);
}
5.
testMapper.xml - myBatis
/* select query */
It's not supposed to work on spring 3.2.9? Should I just use Field Injection?
(Additing, the project can't use Lombok.)
You are using an ancient and unsupported version of Spring, which I highly recommend to upgrade to something that is supported (like 5.3.x or even the 6 although that last one might be a bridge too far).
The error tells you what is wrong, albeit a bit of a cryptic one.
BeanCreationException(Error creating bean with name...), AopConfigException(could not generate CGLIB...), IllegalArgumentException(Super class has no null constructor but no arguments were given).
The null constructor
is a default no-args constructor as that is still needed in this version of Spring. The proxy needs a no-args constructor, so you need to add it. (This restriction has been lifted in later versions of Spring).
@Controller
@RequestMapping("/test/something")
public class TestController {
private final TestService testService;
public TestController() {
this(null);
}
@Autowired
public TestController (TestService testService){
this.testService = testService;
}
}
The controller above has a no-args constructor added, as your field is final
you need to assign a value to it. I find it always better to chain the constructor and thus call this(null)
which will invoke the TestController(TestService testService)
constructor with a null
value.
However the fact that you need this constructor highlights, imho, a bigger issue you have and that is that you are using AOP to apply some logic to classes. It appears to me, without knowing what you are doing, that you are applying it too broadly.