Learning spring of automatic assembly 6-bean

Spring: Automatic Assembly

Bean's automated assembly

  • Automatic spring assembly using a method satisfying dependent bean
  • spring will look for their dependent bean is a bean in the application context.

Spring assembly mechanism in three bean, namely:

  1. Explicit arranged in xml;
  2. Explicit arranged in java;
  3. Implicit bean discovery mechanism and automatic assembly.

Here we talk about the third: automated assembly bean.

Spring needs to achieve automatic assembly from two angles, or that two operations:

  1. Scanning component (component scanning): spring bean automatically find application context created;
  2. Automatic assembly (autowiring): spring automatically satisfy the dependencies between the bean, that is, we say the IOC / DI;

Scanning and automatic assembly configuration component composition play great power, so that the display is reduced to a minimum.

It recommended not to use automated assembly xml configuration, and use notes.

Environment to build

A person has two pets

public class Dog {
    public void shout() {
        System.out.println("wang~");
    }
}
public class Cat {
    public void shout() {
        System.out.println("miao~");
    }
}
public class Person {
    private Cat cat;
    private Dog dog;
    
    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public Cat getCat() {
        return cat;
    }

    public Dog getDog() {
        return dog;
    }
}

xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="dog" class="com.cong.pojo.Dog"/>
    <bean id="cat" class="com.cong.pojo.Cat"/>
    <bean id="person" class="com.cong.pojo.Person">
        <property name="name" value="cong"/>
        <property name="dog" ref="dog"/>
    </bean>
</beans>

test

public class TestAuto {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) context.getBean("person");
        person.getCat().shout();
        person.getDog().shout();
    }
}

ok, no problem

byName

autowire byName (automatic assembly by name)

Xml since manual configuration process, and capitalization letters and gaps often occurs an error, and can not be checked, so as to reduce the efficiency of development.

Automatic assembling will avoid these errors, and easy to configure.

<bean id="person2" class="com.cong.pojo.Person" autowire="byName"/>

test

    @Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) context.getBean("person2");
        person.getCat().shout();
        person.getDog().shout();
    }

Test no problem!

Do a little modification

The cat's bean id change it

 <bean id="cat1" class="com.cong.pojo.Cat"/>

Again test errorjava.lang.NullPointerException

Because according to the rules byName not find a corresponding set method, there is no real setCat execution, the object is not initialized, it will report a null pointer error when calling.

summary:

When a node with a bean property of autowire byName.

  1. The method finds all the set of its class name, for example setCat, obtaining the first set and remove the lowercase character string, i.e., cat.
  2. Go look for spring container if there is this string name of the object id.
  3. If so, remove the injection; if not, a null pointer exception reported.

byType

autowire byType (autowiring by type)

Use autowire byType first need to ensure that: objects of the same type, the only vessel in the spring.

If not unique, it is not the only exception will be reported NoUniqueBeanDefinitionException.

<bean id="person3" class="com.cong.pojo.Person" autowire="byType"/>

Test, no problem

    @Test
    public void test3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) context.getBean("person3");
        person.getCat().shout();
        person.getDog().shout();
    }

At this time, we registered a cat2

    <bean id="cat" class="com.cong.pojo.Cat"/>
    <bean id="cat2" class="com.cong.pojo.Cat"/>

Run, you will get an error

NoUniqueBeanDefinitionException

Commented cat

    <!--<bean id="cat" class="com.cong.pojo.Cat"/>-->
    <bean id="cat2" class="com.cong.pojo.Cat"/>

Test, you can, because it is assembled by type, so it does not announce an exception, it does not affect the final result. Even the id attribute removed, does not affect the results.

Use annotations

jdk1.5 began to support annotations, spring2.5 began full support annotations.

Use annotations need to introduce context header in the configuration file, write directly on the idea of <context:context:annotation-configa carriage return is automatically imported.

And open support for annotations<context:annotation-config/>

@Autowired

  • @Autowired is by type of automatic assembly, id does not match the support.
  • You need to import the spring-aop package!
  • If a plurality of the same type of bean, automatically assembling the class name lowercase bean,

A new class Pserson removed setter

public class Person2 {
    @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;

    public Cat getCat() {
        return cat;
    }

    public Dog getDog() {
        return dog;
    }
}

Re-create a configuration file, beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <context:annotation-config/>
    <bean id="dog" class="com.cong.pojo.Dog"/>
    <bean id="cat" class="com.cong.pojo.Cat"/>
    <bean id="person2" class="com.cong.pojo.Person2"/>
</beans>

Test, no problem

    @Test
    public void test4(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person2 person2 = (Person2) context.getBean("person2");
        person2.getCat().shout();
        person2.getDog().shout();
    }

@Autowired extension

@Autowired can set properties required

Description:

false, the object can be null;

true, the object must exist objects can not be null.

//如果允许对象为null,设置required = false,默认为true
@Autowired(required = false)
private Cat cat;

@Qualifier

  • @Autowired according to the type of automatic assembly, the assembly may be automatically coupled @Qualifier manner according byName
  • @Qualifier not be used alone.

Beans.xml modify the contents of the configuration file, and add dog2 cat2

    <context:annotation-config/>
    <bean id="dog" class="com.cong.pojo.Dog"/>
    <bean id="dog2" class="com.cong.pojo.Dog"/>
    <bean id="cat" class="com.cong.pojo.Cat"/>
    <bean id="cat2" class="com.cong.pojo.Cat"/>
    <bean id="person2" class="com.cong.pojo.Person2"/>

Run, can, @ autowired assembly will automatically default type lowercase bean

Modified again, ensure the existence of the object type. And the name is not the default name of the class!

    <context:annotation-config/>
    <bean id="dog1" class="com.cong.pojo.Dog"/>
    <bean id="dog2" class="com.cong.pojo.Dog"/>
    <bean id="cat1" class="com.cong.pojo.Cat"/>
    <bean id="cat2" class="com.cong.pojo.Cat"/>
    <bean id="person2" class="com.cong.pojo.Person2"/>

If this time is no longer Person2 write @qualifier, will error

Add Qualifier annotation on the property

    @Autowired
    @Qualifier(value = "cat2")
    private Cat cat;
    @Autowired
    @Qualifier(value = "dog2")
    private Dog dog;

In this way, the test would be no problem

@Resource

  • @Resource if specified attribute name, attribute byName the press fitting manner lookup;
  • Secondly, then the default byName assembled manner;
  • If the above are not successful, press byType way automatic assembly.
  • Not successful, reported abnormal.

Entity class

public class Person3 {
    //如果允许对象为null,设置required = false,默认为true
    @Resource(name = "cat2")
    private Cat cat;
    @Resource
    private Dog dog;

    public Cat getCat() {
        return cat;
    }

    public Dog getDog() {
        return dog;
    }
}

Then create a new profile beans2.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <context:annotation-config/>
    <bean id="dog" class="com.cong.pojo.Dog"/>
    <bean id="cat1" class="com.cong.pojo.Cat"/>
    <bean id="cat2" class="com.cong.pojo.Cat"/>
    <bean id="person3" class="com.cong.pojo.Person3"/>
</beans>

Test, no problem

    //@resource
    @Test
    public void test5(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
        Person3 person3 = (Person3) context.getBean("person3");
        person3.getCat().shout();
        person3.getDog().shout();
    }

At this time, delete cat2

    <bean id="dog" class="com.cong.pojo.Dog"/>
    <bean id="cat1" class="com.cong.pojo.Cat"/>
    <!--<bean id="cat2" class="com.cong.pojo.Cat"/>-->
    <bean id="person3" class="com.cong.pojo.Person3"/>
</beans>

Leaving only entity class notes

    @Resource//(name = "cat2")
    private Cat cat;
    @Resource
    private Dog dog;

Test, or no problem

Conclusion: The first were byName lookup failure; then byType find, success.

summary

@Autowired and @Resource similarities and differences:

  1. @Autowired assembly can be used with @Resource bean. Can be written in the field, or write on the setter methods.
  2. Default fitting @Autowired by type (belonging to the spring specifications), by default in claim dependent objects must be present, if you want to allow null values, can set its required property is false, such as: @Autowired (required = false), if we want assembly may be combined with the name used for annotations @Qualifier
  3. @Resource (forever, the J2EE), assembled in accordance with a default name, which can be specified by the name attribute. If you do not specify a name attribute, when the notes written on the field, take the default field name lookup by name, if the notes written on the attribute setter methods to take default name for assembly. When that matches the name can not be found when assembled in accordance with the type of bean. However, note that if the name attribute if specified, will only be assembled by name.

Their role is injected into the same object with the annotation mode, but a different order of execution. @Autowired first byType, @ Resource to byName.

Guess you like

Origin www.cnblogs.com/ccoonngg/p/12026755.html