spring-配置小结

 
 
 
 

传统的spring是xml与java代码相结合。

xml部分:

<bean id="dog" class="demo.entity.Dog">
        <property name="name" value="dog wangwang.."/>
    </bean>

    <bean id="person" class="demo.entity.Person">
        <constructor-arg name="age" value="18"/>
        <constructor-arg name="name" value="human"/>
        <!-- 装配对象之间的关系-->
        <constructor-arg name="pet" ref="dog"/>
    </bean>


java部分:

public class Dog{

    String name = "dog wangwang..";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

public class Person {

    String name;

    int age = 18;

    Dog pet;

    public Person(Dog pet,String name, int age) {
        this.name = name;
        this.age = age;
        this.pet = pet;
    }

    public Dog getPet() {
        return pet;
    }

    public void setPet(Dog pet) {
        this.pet = pet;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}


ApplicationContext context = new ClassPathXmlApplicationContext("/spring.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person.getName());
        System.out.println(person.getAge());
        System.out.println(person.getPet().getName());

输出:

human
18
dog wangwang..

一个应用程序有多少个Bean你自己心里没点数??

so。。。




spring2.5引入注解装配,这种方式的装配只要由两部分组成

1.自动扫描:

将你需要的bean纳入spring管理,而spring为纳入的bean主要区分为四大类。消除xml中bean元素的定义。

spring容器对于所有的bean分为了以下四类:


@Component 通用注解,仅标识为spring组件。

@Controller 定义为SpringMvc Controller。

@Repository

1.标识为数据仓库 

2.将被@Repository注解的类添加一个通知器,这样就可以捕获mybatis,hibernate等第三方持久层框架相关的异常,然后以spring的非检查型异常形式重新抛出。

@Service 标识为服务。


2.自动装配:

为bean之间建立依赖关系,主要有四种方式装配置。

byName:

按照bean的id来装配,如果没有指定id,id默认为bean的类名,首字母小写,比如bean:CityPerson,默认id为cityPerson。


byType:

寻找类型进行匹配,有多个bean可以匹配的时候,可以标识其中一个类标识为首选bean(将其他的bean设置为primary=false),或者将不需要进行装配的bean进行排除(将其他的bean设置为autowire-condidate=false


constrictor:

通过构造函数进行装配。


自动匹配:

首先尝试constrictor匹配,否则进行byType尝试.


spring默认关闭这种注解装配方式,因此必须在配置中开启注解装配配置,xml需要加上以下配置。

<!-- 扫描package,将需要的bean纳入spring管理 -->
    <context:component-scan base-package="demo.*"/>
    <!-- 开启注解装配 -->
    <context:annotation-config/>



spring提供以下三种自动装配的注解:

@Autwired

spring自带的注解,可装配null,装配方式为byType,当type匹配多个时,可以将byType注入转换为byName注入,使用@Qualifier来完成转换并缩小bean的范围。

@Inject

java标准 JSR-330,强装配,不可为null,装配方式为byType。当装配多个bean时,将byType注入转换为byName注入,使用@Named缩小bean范围。

@Resource

java标准 JSR-250,强装配,不可为null,先byName,后byType。


spring自带的装配注解 @Auowired

public interface Animal {
    String say();
}

@Component
public class Cat implements Animal {
    public String say() {
        return this.getClass().getName();
    }
}

@Component
public class Dog implements Animal {
    public String say() {
        return this.getClass().getName();
    }
}

@Component
public class Person {

    @Autowired
    private Animal animal;

    public Animal getAnimal() {
        return animal;
    }

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}


ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person.getAnimal().say());


报错信息如下


spring没有找到相应animal类型,但是cat和dog这两个bean可以匹配上。这时我们缩小bean的范围到cat.代码改为。

@Component
public class Person {

    @Autowired
    @Qualifier("cat")
    private Animal animal;

    public Animal getAnimal() {
        return animal;
    }

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}

或者代码改为

@Component
public class Person {

    @Autowired
    private Animal cat;

    public Animal getCat() {
        return cat;
    }

    public void setCat(Animal cat) {
        this.cat = cat;
    }
}

或者代码改为

@Component
@Primary
public class Cat implements Animal {
    public String say() {
        return this.getClass().getName();
    }
}

@Component
public class Person {

    @Autowired
    private Animal animal;

    public Animal getAnimal() {
        return animal;
    }

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}


三种方法正常输出:

demo.entity.Cat


第一种:缩小bean的范围。

第二种:按照名称来装配,找到id为cat的bean。

第三种:设置Cat为首选bean。

一般来说使用第一种用@Autowired和@Qualifier比较多,后两者比较少。


JSR-330的装配注解基本上可以完全替换spring的注解,这种方式的注解需要引用额外的jar包。

maven依赖为

<!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>


@Inject替换@Autowired,@Named替换@Qualifier,代码改为

@Component
public class Person {

    @Inject
    @Named("cat")
    private Animal animal;

    public Animal getAnimal() {
        return animal;
    }

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}



两种注解混用

@Component
@Primary
public class Cat implements Animal {
    public String say() {
        return this.getClass().getName();
    }
}

@Component
public class Person {

    @Inject
    private Animal animal;

    public Animal getAnimal() {
        return animal;
    }

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}

两种都输出:

demo.entity.Cat


最后还有一种JSR-250提供的@Resource注解进行装配,和@Inject不同的是,该注解是在rt包下,因此不需要引用任何其他maven依赖。

@Resource注解首先进行名称匹配,不成功则进行类型匹配,两种匹配都没有找到对应的bean,则抛出异常。

验证先名称,后类型匹配规则,代码改为:

Person类



Cat类没有继承Animal。



继承了Animal的Dog类。



测试代码

 ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person.getCat().say());


spring先去找了Cat这个类,发现并不是Animal的子类,然后他并没有继续去找Dog类,而是选择了抛出错误信息。很显然,@Resource确实是先名称,后类型的顺序去注入的。




显示指定名称匹配

@Component
public class Person {

    @Resource(name = "cat")
    private Animal animal;

    public Animal getAnimal() {
        return animal;
    }

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }

}

显示指定类型匹配

@Component
public class Person {

    @Resource(type = Cat.class)
    private Animal animal;

    public Animal getAnimal() {
        return animal;
    }

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }

}


spring虽然可以将bean纳入管理,并且建立bean之间的依赖管理。但是我们知道,java还有八种基本类型以及字符串类型等,spring该如何处理呢。

这时你可以想到我们可以直接在java中作赋值操作。这当然是对的,但是我们也可以通过spring对于基本类型进行注入。而且是动态的。

关于@Value如何动态创建值,请搜索其他相关文章。


//@Component注解的bean被spring扫描到了之后自动纳入spring管理。
@Component
public class Person {

    //通过spring的@Value动态注入属性值
    @Value("human")
    String name;

    @Value("18")
    int age = 18;

    //自动注入,建立bean之间的依赖关系
    @Autowired
    Dog pet;

//    public Person(Dog pet,String name, int age) {
//        this.name = name;
//        this.age = age;
//        this.pet = pet;
//    }

    public Dog getPet() {
        return pet;
    }

    public void setPet(Dog pet) {
        this.pet = pet;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}



总结一下:

1.spring装配有四种方式,分别是名称匹配,类型匹配,构造函数匹配,自动匹配(先构造函数,后type)。

2.spring注解装配提供三种方式,分别是spring自带的@Autowired,JSR-330的@Inject,JSR-250的@Resource。

3.@Autowired可装配null,先按照type进行匹配,匹配多个时,可匹配@Qualifier注解进行bean的范围锁定。

4.spring提供@Primary将bean标记为首选bean。

5.@Inject不可装配null,和@Autowired一样按照type进行装配,匹配多个时用@Named进行bean的范围锁定。

6.@Resource不可装配null,先按照名称匹配,否则按照类型匹配。



资料:

http://blog.csdn.net/u012734441/article/details/51706504

http://blog.csdn.net/baple/article/details/17891755

http://blog.csdn.net/ethanwhite/article/details/51879871



猜你喜欢

转载自blog.csdn.net/helianus/article/details/78721901