springboot 框架下对象使用时new()和注解注入的区别
一、验证结论:
如果对象由注解注入则对象初始化时只是简单的调用空构造函数,属性则为默认值
如果为new()对象,赋值是什么就是什么
package com.gxb.crawler.contoller; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class B { @Resource public A a; @GetMapping("/test") public void test1() { System.out.println(a);//如果是注解注入A对象,注意此时A的初始化 只是简单的调用A的空构造函数,A中的属性默认都是默认值(int是0,类属性是null),A中的属性如果自定义了赋值,也不会被使用。 System.out.println(a.as); System.out.println(a.aa); //a.setAa(222); //System.out.println(a.aa); //a.c.foo(); //System.out.println(a.c); a.run(); System.out.println(a.aaa); } } @Repository class A { public void setAa(int aa) { this.aa = aa; } /** * 属性初始化的顺序是在构造器之前,编译器也会先设置默认值,然后赋予指定值 * 但是当该类的实例是spring注解的注入方式,那么被指定的值不会被赋值 */ public int aa=1;//定义到C的前面,会被先于C初始化 public String as="sdfsdf";//如果该类的对象是springMVC注解注入的方式,那么这个属性默认是null,即使赋值,也是空 @Resource public C c ; //不会被初始化 如果 = new C(); 会先于aa和aaa初始化 // public C getC() { // return c; // } public int aaa=2;//定义到C的后面,但是 C不会被初始化 public void run(){ System.out.println("aaaaa"); c.foo(); } } @Component class C { public C() { System.out.println("C..init.."); } public void foo(){ System.out.println("cccc"); } }
执行后:
修改后;
package com.gxb.crawler.contoller; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class B { //@Resource public A a =new A(); @GetMapping("/test") public void test1() { System.out.println(a);//如果是注解注入A对象,注意此时A的初始化 只是简单的调用A的空构造函数,A中的属性默认都是默认值(int是0,类属性是null),A中的属性如果自定义了赋值,也不会被使用。 System.out.println(a.as); System.out.println(a.aa); //a.setAa(222); //System.out.println(a.aa); //a.c.foo(); //System.out.println(a.c); //a.run(); System.out.println(a.aaa); } } @Repository class A { public void setAa(int aa) { this.aa = aa; } /** * 属性初始化的顺序是在构造器之前,编译器也会先设置默认值,然后赋予指定值 * 但是当该类的实例是spring注解的注入方式,那么被指定的值不会被赋值 */ public int aa=1;//定义到C的前面,会被先于C初始化 public String as="sdfsdf";//如果该类的对象是springMVC注解注入的方式,那么这个属性默认是null,即使赋值,也是空 @Resource public C c ; //不会被初始化 如果 = new C(); 会先于aa和aaa初始化 // public C getC() { // return c; // } public int aaa=2;//定义到C的后面,但是 C不会被初始化 public void run(){ System.out.println("aaaaa"); c.foo(); } } @Component class C { public C() { System.out.println("C..init.."); } public void foo(){ System.out.println("cccc"); } }
执行结果:
解开a.run()注释
public void test1() { System.out.println(a);//如果是注解注入A对象,注意此时A的初始化 只是简单的调用A的空构造函数,A中的属性默认都是默认值(int是0,类属性是null),A中的属性如果自定义了赋值,也不会被使用。 System.out.println(a.as); System.out.println(a.aa); //a.setAa(222); //System.out.println(a.aa); //a.c.foo(); //System.out.println(a.c); a.run(); System.out.println(a.aaa); } }
结果:换为new()对象A,则A内用注解注入的C不可用
二、验证注解方式的调用:
public void test1() { System.out.println(a);//如果是注解注入A对象,注意此时A的初始化 只是简单的调用A的空构造函数,A中的属性默认都是默认值(int是0,类属性是null),A中的属性如果自定义了赋值,也不会被使用。 System.out.println(a.as); System.out.println(a.aa); //a.setAa(222); //System.out.println(a.aa); //a.c.foo(); System.out.println(a.c); a.run(); System.out.println(a.aaa); }
执行结果:
public void test1() { System.out.println(a);//如果是注解注入A对象,注意此时A的初始化 只是简单的调用A的空构造函数,A中的属性默认都是默认值(int是0,类属性是null),A中的属性如果自定义了赋值,也不会被使用。 System.out.println(a.as); System.out.println(a.aa); //a.setAa(222); //System.out.println(a.aa); a.c.foo(); System.out.println(a.c); a.run(); System.out.println(a.aaa); }
执行结果:
结论:a.c.too()不能直接使用,因为a.c是null,可以使用GET方法
public class B { @Resource public A a; @GetMapping("/test") public void test1() { System.out.println(a);//如果是注解注入A对象,注意此时A的初始化 只是简单的调用A的空构造函数,A中的属性默认都是默认值(int是0,类属性是null),A中的属性如果自定义了赋值,也不会被使用。 System.out.println(a.as); System.out.println(a.aa); //a.setAa(222); //System.out.println(a.aa); a.getC().foo(); System.out.println(a.getC()); a.run(); System.out.println(a.aaa); } } @Repository class A { public void setAa(int aa) { this.aa = aa; } /** * 属性初始化的顺序是在构造器之前,编译器也会先设置默认值,然后赋予指定值 * 但是当该类的实例是spring注解的注入方式,那么被指定的值不会被赋值 */ public int aa=1;//定义到C的前面,会被先于C初始化 public String as="sdfsdf";//如果该类的对象是springMVC注解注入的方式,那么这个属性默认是null,即使赋值,也是空 @Resource public C c ; //不会被初始化 如果 = new C(); 会先于aa和aaa初始化 public C getC() { return c; } public int aaa=2;//定义到C的后面,但是 C不会被初始化 public void run(){ System.out.println("aaaaa"); c.foo(); } }
执行结果:
通过直接给属性赋值,改变初始值
public void test1() { System.out.println(a);//如果是注解注入A对象,注意此时A的初始化 只是简单的调用A的空构造函数,A中的属性默认都是默认值(int是0,类属性是null),A中的属性如果自定义了赋值,也不会被使用。 // System.out.println(a.as); System.out.println(a.aa=1); //a.setAa(222); System.out.println(a.aa); // a.getC().foo(); // System.out.println(a.getC()); // a.run(); // System.out.println(a.aaa); }
执行结果;
使用set方法
public void test1() { System.out.println(a);//如果是注解注入A对象,注意此时A的初始化 只是简单的调用A的空构造函数,A中的属性默认都是默认值(int是0,类属性是null),A中的属性如果自定义了赋值,也不会被使用。 // System.out.println(a.as); //System.out.println(a.aa=1); a.setAa(222); System.out.println(a.aa); // a.getC().foo(); // System.out.println(a.getC()); // a.run(); // System.out.println(a.aaa); }
使用set方法赋值,不好使