Spring-基于注解的配置[02自动装载bean](上)

简介: Spring-基于注解的配置[02自动装载bean]

使用@Autowired进行自动注入


Spring通过@Autowired注解实现Bean的依赖注入。


@Autowired默认按照类型(byType)匹配的方式在容器中查找匹配的Bean,当且仅有一个匹配的Bean时,Spring将其注入@Autowired标注的变量中。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Pilot {
    @Autowired
    private Plane plane;
    public void drivePlane() {
        plane.fly();
    }
}


实例

20170724103750715.jpg


POJO类

package com.xgj.ioc.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Pilot {
    @Autowired
    private Plane plane;
    public void drivePlane() {
        plane.fly();
    }
}


@Component注解将Pilot标注为一个Bean,Spring会扫描加载并实例化该Bean。

通过@Autowired注入plan的Bean。


POJO类

package com.xgj.ioc.configuration;
import org.springframework.stereotype.Component;
@Component
public class Plane {
    private String brand;
    private String color;
    private int speed;
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public int getSpeed() {
        return speed;
    }
    public void setSpeed(int speed) {
        this.speed = speed;
    }
    public void introduce() {
        System.out.println("Plane information【 brand:" + brand + ",color:"
                + color + ",speed:" + speed);
    }
    public void fly() {
        System.out.println("Plane begins to  fly");
    }
}

配置文件

<?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 
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- (1)声明Context命名空间以及Schema文件   (2)扫描类包以及应用注解定义的bean -->
    <context:component-scan base-package="com.xgj.ioc.configuration"/>
</beans>

测试类

package com.xgj.ioc.configuration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ConfigBeanTest {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "classpath:com/xgj/ioc/configuration/beans.xml");
        Pilot pilot = ctx.getBean("pilot", Pilot.class);
        pilot.drivePlane();
        Plane plane = ctx.getBean("plane", Plane.class);
        plane.setBrand("A380");
        plane.setColor("White");
        plane.setSpeed(800);
        plane.introduce();
    }
}


运行结果:


20170724104150877.jpg


使用@Auotwired的required属性


如果容器中没有一个和标注变量类型匹配的Bean,那么Spring启动的时候会报NoSuchBeanDefinitionException异常。 如果希望Spring及时找不到匹配的Bean完成注入也不要抛出异常,那么就可以使用@Autowired(required=false)进行标注。


实例

还是以上面的例子为基础改造下,我们知道上面的扫描包配置的为

<context:component-scan base-package="com.xgj.ioc.configuration"/>


假设在com.xgj.ioc.configuration之外的包目录下 有个Tank类(com.xgj.ioc.inject.construct.type.Tank)


改造下Pilot类,引入Tank,设置自动注入


package com.xgj.ioc.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.xgj.ioc.inject.construct.type.Tank;
@Component
public class Pilot {
    @Autowired
    private Plane plane;
    @Autowired
    private Tank tank;
    public void drivePlane() {
        plane.fly();
    }
}

@Autowired 默认 required =true

运行测试类:

No qualifying bean of type 'com.xgj.ioc.inject.construct.type.Tank' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}



20170724112218817.jpg

我们改造下@Autowired(required = false)

@Autowired(required = false)
private Tank tank;


再此运行: OK

20170724112527629.jpg


使用@Qualifier指定注入Bean的名称


如果容器中有一个以上匹配的Bean时,则可以通过@Qualifier注解限定Bean的名称。


假设容器中有两个类型为Plane的Bean,一个名为plane,一个名为otherPlane. 因为@Autowired默认是按照类型匹配的方式在容器中查找,plane和otherPlane的类型都是Plane,怎么知道注入哪一个呢?


实例

20170724122102206.jpg

我们在扫描的基类包下增加个子包 other,包下新增同名Plane类,通过@Component(“otherPlane”)指定Bean的名称。

com.xgj.ioc.configuration.other.Plane代码如下:

package com.xgj.ioc.configuration.other;
import org.springframework.stereotype.Component;
@Component("otherPlane")
public class Plane {
    private String brand;
    private String color;
    private int speed;
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public int getSpeed() {
        return speed;
    }
    public void setSpeed(int speed) {
        this.speed = speed;
    }
    public void introduce() {
        System.out.println("OtherPlane information【 brand:" + brand + ",color:"
                + color + ",speed:" + speed);
    }
    public void fly() {
        System.out.println("OtherPlane begins to  fly");
    }
}


如果我们希望注入otherPlane呢?

我们来改造Pilot类

package com.xgj.ioc.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
// 1. 引入其他子包下的Plane  
import com.xgj.ioc.configuration.other.Plane;
import com.xgj.ioc.inject.construct.type.Tank;
@Component
public class Pilot {
    @Autowired
    // 2 通过@Qualifier限定Bean的名称
    @Qualifier("otherPlane")
    private Plane plane;
    @Autowired(required = false)
    private Tank tank;
    public void drivePlane() {
        plane.fly();
    }
}


测试类中改动的地方

记得引入 other子包下的Plane

import com.xgj.ioc.configuration.other.Plane;
.....
Plane plane = ctx.getBean("otherPlane", Plane.class);


然后运行测试类:


20170724122721459.jpg

对类方法进行标注


@Autowired可以对类成员变量以及方法的入参进行标注。

下面在类的方法上使用@Autowired注解。


实例


20170730012623804.jpg

package com.xgj.ioc.configuration.method;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Pilot {
    private Plane plane;
    // 自动将Plane类型传给方法入参
    @Autowired
    public void setPlane(Plane plane) {
        this.plane = plane;
    }
    public void drivePlane() {
        plane.fly();
    }
}

如果是下面这种写法

    // 自动将名为plane的Bean传给方法入参
    @Autowired
    @Qualifier("plane")
    public void setPlane(Plane plane) {
        this.plane = plane点内容**


如果一个方法拥有多个入参,在默认情况下,Spring将自动选择匹配入参类型的Bean进行注入。 Spring允许对方法入参标注@Qualifier以指定注入Bean的名称。

比如

@Autowired
    public void setPlane(Plane plane, @Qualifier("tank") Tank tank) {
        this.plane = plane;
    }


在这种情况下,Plane的入参注入为Plane类型的Bean,而Tank的入参注入的则为名称为tank的Bean.

实例代码如下:

Pilot POJO类

package com.xgj.ioc.configuration.method;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Pilot {
    private Plane plane;
    // 自动将Plane类型传给方法入参
    @Autowired
    public void setPlane(Plane plane) {
        this.plane = plane;
    }
    public void drivePlane() {
        plane.fly();
    }
}


Plane POJO类

package com.xgj.ioc.configuration.method;
import org.springframework.stereotype.Component;
@Component // 通过注解标注为一个Bean,以便Spring扫描并实例化
public class Plane {
    public void fly() {
        System.out.println("Plane begins to  fly");
    }
}


配置文件

<?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 
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- (1)声明Context命名空间以及Schema文件   (2)扫描类包以及应用注解定义的bean -->
    <context:component-scan base-package="com.xgj.ioc.configuration.method"/>
</beans>



测试类

package com.xgj.ioc.configuration.method;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ConfigMethodTest {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "classpath:com/xgj/ioc/configuration/method/beans.xml");
        Pilot pilot = ctx.getBean("pilot", Pilot.class);
        pilot.drivePlane();
    }
}


运行结果



20170730014452248.jpg


相关文章
|
15天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
36 0
|
1月前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
12天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
32 0
|
1月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
38 0
|
30天前
|
Java API Spring
在 Spring 配置文件中配置 Filter 的步骤
【10月更文挑战第21天】在 Spring 配置文件中配置 Filter 是实现请求过滤的重要手段。通过合理的配置,可以灵活地对请求进行处理,满足各种应用需求。还可以根据具体的项目要求和实际情况,进一步深入研究和优化 Filter 的配置,以提高应用的性能和安全性。
|
18天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
22天前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
45 4
SpringBoot必须掌握的常用注解!
|
22天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
30 1
|
24天前
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
80 2
|
24天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
35 1
下一篇
无影云桌面