关闭

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

标签: spring注解annotation
927人阅读 评论(0) 收藏 举报
分类:

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的名称作为键值。
1
0
查看评论

Spring通过注解配置bean

配置 bean有两种方式:基于 XML 文件的方式;基于注解的方式(基于注解配置 Bean;基于注解来装配 Bean 的属性)之前我们都是在IOC配置文件xml中配置bean,现在我们尝试在代码源文件中通过注解的方式标注特定类对应的Bean。在 classpath 中扫描组件组件扫描(compone...
  • StubbornAccepted
  • StubbornAccepted
  • 2017-04-25 18:10
  • 181

Spring通过注解配置bean

简介及测试  Spring支持通过注解的方式来配置bean实例。Spring能够从classpath下自动扫描,侦测和实例化具有特定注解的组件。特定组件包括:   @Component:基本注解,标识了一个受Spring管理的组件。   @Repository:标识持久层组件。   @Serv...
  • xiangwanpeng
  • xiangwanpeng
  • 2016-12-25 11:38
  • 641

Spring全家桶(二)Bean之间的关系、自动装配、作用域和使用外部文件

五、Bean的自动装配Spring IOC容器可以自动装配Bean,需要在bean的autowire属性里指定自动装配的模式。<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="...
  • napoay
  • napoay
  • 2017-05-16 11:25
  • 1144

转载的spring cloud的全家桶,有空学习下

Spring Cloud Config:配置管理开发工具包,可以让你把配置放到远程服务器,目前支持本地存储、Git以及Subversion。  Spring Cloud Bus:事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署...
  • ivan0609
  • ivan0609
  • 2017-06-22 14:55
  • 1407

Spring全家桶(九)Spring JdbcTemplate

一、Spring JDBCSpring JDBC是在JDBC API的基础上定义一个抽象层,用以简化JDBC操作。Spring JdbcTemplate是Spring JDBC框架的核心,为不同类型的JDBC操作提供模板方法,每个模板方法都能控制整个过程,并允许覆盖过程中的特定任务。基于此,可以在保...
  • napoay
  • napoay
  • 2017-05-31 13:24
  • 1896

Spring Cloud全家桶主要组件及简要介绍

一、微服务简介微服务是最近的一两年的时间里是很火的一个概念。感觉不学习一下都快跟不上时代的步伐了,下边做一下简单的总结和介绍。何为微服务?简而言之,微服务架构风格这种开发方法,是以开发一组小型服务的方式来开发一个独立的应用系统的。其中每个小型服务都运行在自己的进程中,并经常采用HTTP资源API这样...
  • u010870518
  • u010870518
  • 2017-09-01 17:30
  • 10479

小姐,来桶全家桶不?(Servlet)

一.前言   小生不才,大二下半学期第二个星期,近11月博客园。星期六闲来看看经典书。重温下Serlvet。 二.温故而知新:超文本转移协议HTTP    HTTP协议是通过互联网(internet)或企业内部网(intranet)交换数据。介绍下http请求,http响应的过程。 ...
  • u010378410
  • u010378410
  • 2014-04-07 08:28
  • 1159

安卓软件全家桶分析,哪些软件是一伙的

所谓全家桶联盟的意思其实是一个软件联盟的概念, 处于软件联盟中的软件都用了同一个sdk(可以理解为插件), 联盟内软件会在用户不知情的情况下相互调用以保证联盟内的软件在你的手机中时刻保证运行。 意义?1.保证随时能给你发推送。2.后台收集用户数据 一。个推全家桶 代码如下:   ...
  • sinat_32538847
  • sinat_32538847
  • 2015-11-05 18:53
  • 1594

React全家桶之React(一)

一开始听说React是在搞AngularJs时候,那个时候正在一边快乐的玩着AngularJs,一边佩服着这个框架的独到之处,什么MVC模式,模块机制,指令,真是让之前只用jquery的我大开眼见(好吧,扯远了...),我接触ReactJs的原因是因为当时网上看到很多争论Angular和React到...
  • github_37240941
  • github_37240941
  • 2017-01-17 21:32
  • 1342

Vuejs全家桶系列(八)--- 组件

Vuejs全家桶系列(八)--- 组件
  • Nate__River
  • Nate__River
  • 2017-12-22 20:01
  • 229
    《从Lucene到Elasticsearch:全文检索实战》
    Lucene、ES、ELK开发交流群:370734940
    Lucene、ES、ELK开发交流
    个人资料
    • 访问:935747次
    • 积分:9246
    • 等级:
    • 排名:第2379名
    • 原创:209篇
    • 转载:2篇
    • 译文:6篇
    • 评论:468条
    StackOverFlow
    http://stackoverflow.com/users/6526424
    统计
    博客专栏
    文章分类
    最新评论