bean id="car" c" />

小言_互联网的博客

spring的自动装配

393人阅读  评论(0)

基于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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场