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


相关文章
|
16天前
|
存储 Java 数据安全/隐私保护
|
5天前
|
运维 Java 程序员
Spring5深入浅出篇:基于注解实现的AOP
# Spring5 AOP 深入理解:注解实现 本文介绍了基于注解的AOP编程步骤,包括原始对象、额外功能、切点和组装切面。步骤1-3旨在构建切面,与传统AOP相似。示例代码展示了如何使用`@Around`定义切面和执行逻辑。配置中,通过`@Aspect`和`@Around`注解定义切点,并在Spring配置中启用AOP自动代理。 进一步讨论了切点复用,避免重复代码以提高代码维护性。通过`@Pointcut`定义通用切点表达式,然后在多个通知中引用。此外,解释了AOP底层实现的两种动态代理方式:JDK动态代理和Cglib字节码增强,默认使用JDK,可通过配置切换到Cglib
|
1天前
|
JSON 前端开发 Java
【JAVA进阶篇教学】第七篇:Spring中常用注解
【JAVA进阶篇教学】第七篇:Spring中常用注解
|
1天前
|
安全 Java 开发者
深入理解Spring Boot配置绑定及其实战应用
【4月更文挑战第10天】本文详细探讨了Spring Boot中配置绑定的核心概念,并结合实战示例,展示了如何在项目中有效地使用这些技术来管理和绑定配置属性。
10 1
|
3天前
|
Java Spring
Spring文件配置以及获取
Spring文件配置以及获取
10 0
|
4天前
|
JavaScript Java 开发者
Spring Boot中的@Lazy注解:概念及实战应用
【4月更文挑战第7天】在Spring Framework中,@Lazy注解是一个非常有用的特性,它允许开发者控制Spring容器的bean初始化时机。本文将详细介绍@Lazy注解的概念,并通过一个实际的例子展示如何在Spring Boot应用中使用它。
17 2
|
5天前
|
前端开发 Java
SpringBoot之自定义注解参数校验
SpringBoot之自定义注解参数校验
15 2
|
9天前
|
Java 微服务 Spring
Spring Boot中获取配置参数的几种方法
Spring Boot中获取配置参数的几种方法
20 2
|
11天前
|
消息中间件 安全 Java
在Spring Bean中,如何通过Java配置类定义Bean?
【4月更文挑战第30天】在Spring Bean中,如何通过Java配置类定义Bean?
20 1
|
11天前
|
Java Spring
springboot自带的@Scheduled注解开启定时任务
springboot自带的@Scheduled注解开启定时任务