您的位置:首页 > 编程语言 > Java开发

spring注入的对象和new的对象到底有啥区别

2016-09-30 19:00 197 查看
在使用springboot过程中,想使用jdbc模板,就是直接在service层注入一个jdbcTemplate属性,然后直接使用,但是又想封装一下,就创建一个类,类中有jdbcTemplate属性,然后再service中调用我封装的jdbc,刚开始没有封装方法的情况下,想在service中直接想注入我的类,然后调用我的类中的jdbc,什么注解都标注好了,结果一直空指针异常,还以为不好使呢,其实这里面有个很大的问题,就是注解注入的对象和new的对象到底有啥区别;

我们知道,new一个对象的时候,初始化顺序是,父类静态块>子类静态块> 父类属性(先系统默认值,后直接你赋予的值) >父类构造器>子类属性>子类构造器

但是当有个注解在属性上的时候,会是啥情况呢?

@Repository
public class A {
/**
* 属性初始化的顺序是在构造器之前,编译器也会先设置默认值,然后赋予指定值
* 但是当该类的实例是spring注解的注入方式,那么被指定的值不会被赋值
*/
public int aa=1;//定义到C的前面,会被先于C初始化
public String as;//如果该类的对象是springMVC注解注入的方式,那么这个属性默认是null,即使赋值,也是空
@Resource
public C c ; //不会被初始化  如果 = new C(); 会先于aa和aaa初始化
public int aaa=2;//定义到C的后面,但是 C不会被初始化
public void run(){
System.out.println("aaaaa");
c.foo();
}
}

@RestController
public class B {
@Resource
public A a = new A();
@RequestMapping("/B")
public  void test1() {

System.out.println(a.as);//如果是注解注入A对象,注意此时A的初始化 只是简单的调用A的空构造函数,A中的属性默认都是默认值(int是0,类属性是null),A中的属性如果自定义了赋值,也不会被使用。
System.out.println(a.aa);
//a.c.foo();
System.out.println(a.c);
System.out.println(a.aaa);
}
}

@Component
public class C {
public C() {
System.out.println("C..init..");
}
public void foo(){
System.out.println("cccc");
}
}

结论:注入的对象,只会调用空参构造函数,且这个对象的所有属性都是默认值,自己手动赋予的值不会被使用,

所以在A中的C类,在B中调用A的时候,创建的A对象的属性都是默认值,所以A对象虽然有了,但是A的属性C却是null,所以在B中直接this.a.c.method()是会报null指针异常的,且是c是null的发生原因。

解决方式:C在A中添加get方法,然后B中使用a.getC()即可获得c的对象,且c的对象也是spring注入的。

备注:以上结论和说明,只是个人总结,包括new一个对象初始化顺序,可能不严谨,没有时间验证,以后会完善
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: