Spring全家桶(七)通过注解配置Bean

简介: Spring是简化j2ee开发的一个框架,通过指定id、类名配置bean虽然简单,但是当bean很多的时候,spring的配置文件会过于臃肿,使用注解技术配置bean使配置更加简介。

Spring是简化j2ee开发的一个框架,通过指定id、类名配置bean虽然简单,但是当bean很多的时候,spring的配置文件会过于臃肿,使用注解技术配置bean使配置更加简介。

一、注解配置bean步骤

注解配置bean的原理是组件扫描,通过在spring配置文件中定义包扫描器,spring就能从classpath下自动扫描、侦测和实例化具有特定注解的bean。

Spring注解有以下四个,位于org.springframework.stereotype目录下。

  1. Component
    基本注解,标识了一个受Spring管理的组件,源码如下:

    package org.springframework.stereotype;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Component {
        String value() default "";
    }
  2. Repository

    标识持久层组件,源码如下:

    package org.springframework.stereotype;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Repository {
        String value() default "";
    }
  3. Service
    标识业务层组件

    package org.springframework.stereotype;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Service {
        String value() default "";
    }
  4. Controller

    标识表现层组件

    package org.springframework.stereotype;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Controller {
        String value() default "";
    }

配置bean的步骤:

  1. 在java类中加上Spring标准
  2. 配置文件中扫类所在的包
  3. IOC容器获取bean

Spring有一个默认的bean命名策略:使用非限定类名,第一个字母小写,或者通过value属性设置。举例,一个UserService类,通过Service注解标准了:

package com.stuspring.annbeans.service;

import org.springframework.stereotype.Service;

/**
 * Created by bee on 17/5/4.
 */

@Service
public class UserService {
    public void add(){
        System.out.println("UserService add..");
    }
}

在Spring的配置文件中定义组件扫描器(注意引入context命名空间):

<?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-4.3.xsd">

<context:component-scan base-package="com.stuspring.annbeans" />

</beans>

现在Bean已经可以使用了,它的id就是类名UserService首字母小写,即userService。获取bean并调用add方法:

package com.stuspring.annbeans;

import com.stuspring.annbeans.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by bee on 17/5/4.
 */
public class Main {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml");

        UserService userService = (UserService) ctx.getBean("userService");
        System.out.println(userService);
        userService.add();
    }
}

打印结果:

com.stuspring.annbeans.service.UserService@c81cdd1
UserService add..

可以通过value属性来设置bean的id,代码如下,这样bean的id就改为uService了。

@Service("uService")
public class UserService {
    public void add(){
        System.out.println("UserService add..");
    }
}

二、组件扫描器中的一些配置

<context:component-scan >可以定义一些属性及配置:

  • base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包及其子包中的所有类。需要扫描多个包时,可以使用逗号分开。
  • 如果仅需要扫描特定的类而不是基类包下的所有类,可以使用resource-pattern属性过滤特定的类。例如:

    <context:component-scan base-package="com.stuspring.annbeans" resource-pattern="repository/8.class"/>
  • <context:exclude-filter>子节点表示排除在外的目标类

  • <context:include-filter>子节点表示要包含的目标类

三、bean直接的关联关系

在UserController类中创建一个UserService对象:

@Controller
public class UserController {

    private UserService userService;

    public void execute(){
        System.out.println("UserController execute...");
        userService.add();
    }
}

这时候获取UserController对象:

public class Main {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml");

        UserController userController = (UserController) ctx.getBean("userController");
        userController.execute();
    }
}

运行会报空指针异常:

Exception in thread "main" java.lang.NullPointerException
    at com.stuspring.annbeans.controller.UserController.execute(UserController.java:18)
    at com.stuspring.annbeans.Main.main(Main.java:15)
UserController execute...

从打印结果中可以看出UserService在UserController类中没有被标准。<context:component-scan>元素会自动注册AutowiredAnnotationBeanPostProcessor实例,该实例可以自动装配具有@Autowired、@Resource、@Inject注解的属性。

在UserService对象上添加注解@Autowired:

@Autowired
private UserService userService;

这样UserService对象就会自动装配上。

@Autowired注解会自动装配具有兼容类型的单个Bean属性:

  1. 构造器、普通字段,一切具有参数的方法都可以用@Autowired注解
  2. 默认情况下,所有使用@Autowired注解的属性都需要被设置。当Spring找不到匹配的Bean装配属性时会抛出异常。若某一属性允许不被设置,可以设置@Autowired注解的required属性为false
  3. 默认情况下, 当IOC容器中存在多个类型兼容的Bean时,通过类型的自动装配将会无法工作,此时可以在@Qualifier注解里提供Bean的名称。Spring允许对方法的入参标注@Qualifier已指定注入的Bean的名称。
  4. @Autowired注解也可以应用在数组类型的属性上,此时Spring会把所有匹配的Bean进行自动装配
  5. @Autowired注解也可以应用在集合属性上,此时Spring读取积累的类型信息,然后自动装配所有与之兼容的Bean。
  6. @Autowired注解用在java.util.map上时,若该map的键值为String,那么Spring将自动装配与之Map类值兼容的Bean,此时Bean的名称作为键值。
目录
相关文章
|
25天前
|
Java 开发者 Spring
【SpringBoot 异步魔法】@Async 注解:揭秘 SpringBoot 中异步方法的终极奥秘!
【8月更文挑战第25天】异步编程对于提升软件应用的性能至关重要,尤其是在高并发环境下。Spring Boot 通过 `@Async` 注解简化了异步方法的实现。本文详细介绍了 `@Async` 的基本用法及配置步骤,并提供了示例代码展示如何在 Spring Boot 项目中创建与管理异步任务,包括自定义线程池、使用 `CompletableFuture` 处理结果及异常情况,帮助开发者更好地理解和运用这一关键特性。
101 1
|
21天前
|
缓存 Java 数据库连接
Spring Boot奇迹时刻:@PostConstruct注解如何成为应用初始化的关键先生?
【8月更文挑战第29天】作为一名Java开发工程师,我一直对Spring Boot的便捷性和灵活性着迷。本文将深入探讨@PostConstruct注解在Spring Boot中的应用场景,展示其在资源加载、数据初始化及第三方库初始化等方面的作用。
44 0
|
5天前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
5天前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
49 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
6天前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
6天前
|
Java 数据库连接 Maven
Spring基础1——Spring(配置开发版),IOC和DI
spring介绍、入门案例、控制反转IOC、IOC容器、Bean、依赖注入DI
Spring基础1——Spring(配置开发版),IOC和DI
|
17天前
|
IDE Java 开发工具
还在为繁琐的配置头疼吗?一文教你如何用 Spring Boot 快速启动,让开发效率飙升,从此告别加班——打造你的首个轻量级应用!
【9月更文挑战第2天】Spring Boot 是一款基于 Spring 框架的简化开发工具包,采用“约定优于配置”的原则,帮助开发者快速创建独立的生产级应用程序。本文将指导您完成首个 Spring Boot 项目的搭建过程,包括环境配置、项目初始化、添加依赖、编写控制器及运行应用。首先需确保 JDK 版本不低于 8,并安装支持 Spring Boot 的现代 IDE,如 IntelliJ IDEA 或 Eclipse。
53 5
|
21天前
|
Java 微服务 Spring
Spring Cloud全解析:配置中心之解决configserver单点问题
但是如果该configserver挂掉了,那就无法获取最新的配置了,微服务就出现了configserver的单点问题,那么如何避免configserver单点呢?
|
19天前
|
Java Spring 开发者
解锁 Spring Boot 自动化配置的黑科技:带你走进一键配置的高效开发新时代,再也不怕繁琐设置!
【8月更文挑战第31天】Spring Boot 的自动化配置机制极大简化了开发流程,使开发者能专注业务逻辑。通过 `@SpringBootApplication` 注解组合,特别是 `@EnableAutoConfiguration`,Spring Boot 可自动激活所需配置。例如,添加 JPA 依赖后,只需在 `application.properties` 配置数据库信息,即可自动完成 JPA 和数据源设置。这一机制基于多种条件注解(如 `@ConditionalOnClass`)实现智能配置。深入理解该机制有助于提升开发效率并更好地解决问题。
33 0
|
19天前
|
Java Spring 开发者
Spring 框架配置属性绑定大比拼:@Value 与 @ConfigurationProperties,谁才是真正的王者?
【8月更文挑战第31天】Spring 框架提供 `@Value` 和 `@ConfigurationProperties` 两种配置属性绑定方式。`@Value` 简单直接,适用于简单场景,但处理复杂配置时略显不足。`@ConfigurationProperties` 则以类级别绑定配置,简化代码并更好组织配置信息。本文通过示例对比两者特点,帮助开发者根据具体需求选择合适的绑定方式,实现高效且易维护的配置管理。
29 0