基于XML的自动装配
default/no:不自动装配
byName: 根据名字进行装配,以属性名作为id,在容器中查找这个组件进行赋值
byType:根据类型进行装配
constructor: 使用构造器*
byName
<bean id="person" class="com.luo.spring.bean.Person" autowire="byName"/>
bean id="car" class="com.luo.spring.bean.Car">
<property name="name" value="宝马"/>
<property name="price" value="7665"/>
</bean>
public class Person {
private String name;
private Car car;
private Integer age;
.......
}
@Test
public void test08() throws SQLException {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring01.xml");
Person person = (Person) applicationContext.getBean("person");
System.out.println(person);
}
结果如下
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=59349:D:\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar;D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\plugins\junit\lib\junit-rt.jar;D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\plugins\junit\lib\junit5-rt.jar;C:\Program bin\rep\com\fasterxml\jackson\core\jackson-annotations\2.10.0\jackson-annotations-2.10.0.jar"
car实例创建完毕。。。
car set赋值。。
Person{name='null', car=Car{price=7665, name='宝马', color='null', map=null}, age=null}
Process finished with exit code 0
找不到则直接赋值为null
byType
这个是通过类型来进行装配。我们知道,不同的组件可以是同一个类型。如果有两个类型一致,那么装配谁呢?所以在使用时要注意是否有多个相同的类型
<bean id="person" class="com.luo.spring.bean.Person" autowire="byType"/>
bean id="car" class="com.luo.spring.bean.Car">
<property name="name" value="宝马"/>
<property name="price" value="7665"/>
</bean>
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=59349:D:\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar;D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\plugins\junit\lib\junit-rt.jar;D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\plugins\junit\lib\junit5-rt.jar;C:\Program bin\rep\com\fasterxml\jackson\core\jackson-annotations\2.10.0\jackson-annotations-2.10.0.jar"
car实例创建完毕。。。
car set赋值。。
Person{name='null', car=Car{price=7665, name='宝马', color='null', map=null}, age=null}
Process finished with exit code 0
找不到也是直接赋值为null
试试两个相同的类型会发生什么
<bean id="car" class="com.luo.spring.bean.Car">
<property name="name" value="宝马"/>
<property name="price" value="7665"/>
</bean>
<bean id="car2" class="com.luo.spring.bean.Car">
<property name="name" value="BWM"/>
<property name="price" value="7665"/>
</bean>
直接报错:Could not autowire. There is more than one bean of ‘Car’ type. Beans: car2,car. Properties: ‘car’ less… (Ctrl+F1)
constructor
<bean id="person" class="com.luo.spring.bean.Person" autowire="constructor"/>
public class Person {
private String name;
private Car car;
private Integer age;
public Person(Car car) {
this.car = car;
}
........
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=57905:D:\IntelliJ Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program bin\rep\com\fasterxml\jackson\core\jackson-annotations\2.10.0\jackson-annotations-2.10.0.jar"
car实例创建完毕。。。
car set赋值。。
car实例创建完毕。。。
car set赋值。。
Person{name='null', car=Car{price=7665, name='宝马', color='null', map=null}, age=null}
Process finished with exit code 0
在执行构造器装配时,会先按照有参构造器参数的类型进行装配,如果存在组件,则进行赋值,不存在,直接为null。如果按照类型找到多个呢?则按照名字进行匹配。
基于注解的自动装配
现在感觉每次都去配置文件中配置很麻烦,有没有更简单的呢?让IOC容器自动帮我们装配答案是使用注解。
在我们使用的类上面添加相应的注解,在配置文件中扫描我们需要的注解,然后进行自动的装配,省时省力啊~~~
@Autowired
原理:先按照类型进行匹配,匹配到一个直接进行注入,匹配到多个,再按照属性的变量名作为id进行匹配,然后在赋值。没有,抛异常。
@Repository
public class MyDao {
public void dao(){
System.out.println("dao...");
}
}
@Service
public class MyService {
@Autowired
private MyDao myDao;
public void myService(){
System.out.println("myService...");
myDao.dao();
}
}
@Controller
public class MyServlet{
@Autowired
private MyService myService;
public void print() {
myService.myService();
}
}
@Test
public void test09() throws SQLException {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring01.xml");
MyServlet myServlet = applicationContext.getBean(MyServlet.class);
myServlet.print();
}
测试一下
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=55334:D:\IntelliJ Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program bin\rep\com\fasterxml\jackson\core\jackson-annotations\2.10.0\jackson-annotations-2.10.0.jar"
myService...
dao...
Process finished with exit code 0
如果忘记其中的某一个注解的配置,会出现什么问题呢?
@Service
public class MyService
private MyDao myDao;
public void myService(){
System.out.println("myService...");
myDao.dao();
}
}
我们都可以猜测到,会出现空指针的异常
因为在MyService 中 myDao 没有进行属性的的注入,那么它就应该是null,调用null的方法肯定会出现空指针异常啊
java.lang.NullPointerException
at com.luo.spring.service.MyService.myService(MyService.java:20)
at com.luo.spring.web.MyServlet.print(MyServlet.java:20)
com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Process finished with exit code -1
@Qualifier
作用就是让spring别用变量名作为id,取一个自定义的名字,当使用时,必须去找到,找不到,直接报错。
@Controller
public class MyServlet{
@Qualifier("我是别名")
@Autowired
private MyService myService;
public void print() {
myService.myService();
}
}
那如果我不想它报错呢?而是给我装配null
@Autowired(required = false) 默认时true,必须找到,找不到直接报错;改成false,不用必须找到,找不到,就null
Autowired作用在方法上,该方法的参数也会按照类型进行自动装配,然后按照变量名进行装配,和上面介绍的是一样的
转载:https://blog.csdn.net/qq_42224683/article/details/108315522