ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring——基于注解配置bean

2021-11-30 16:03:03  阅读:161  来源: 互联网

标签:Autowired Spring BookService bean 组件 注解 public


文章目录

一、通过注解分别创建Dao,Service,Controller

1.为什么使用注解?

如果按照之前xml的方法进行配置,存在多个bean都需要一一配置,当这些bean特别多且繁杂的时候,一个一个的配置不符合人类的天性(懒),那么注解就油然而生。当我们创建bean类时,只需要优雅的在类名上面加上一行轻飘飘的注解,一个bean就被我们装到了bean的空间中。

2.表示组件(bean)的四大注解

  • Controller:表述层控制器组件,标识一个受 Spring IOC 容器管理的控制层控制器组件(可以理解为一个servlet)
  • Service :业务逻辑层组件,标识一个受 Spring IOC 容器管理的业务逻辑层组件(可以理解为一个service)
  • Repository:持久化层组件,标识一个受 Spring IOC 容器管理的持久化层组件(可以理解为Dao)
  • Component :普通组件,标识一个受 Spring IOC(啥都可以表示)

组件命名规则

① 默认情况:使用组件的简单类名首字母小写后得到的字符串作为 bean 的 id

②使用组件注解的 value 属性指定 bean 的 id 注意:事实上 Spring 并没有能力识别一个组件到底是不是它所标记的类型,即使将 @Respository 注解用在一个表述层控制器组件上面也不会产生任何错误。由此见得,这些组件其实没有多大的区别,只是为了程序猿进行逻辑上的区分。

二、扫描组件

这些组件加了注解后,如果不进行扫描的话,也无法进入bean的管理空间,在扫描组件之前,需要引入配置

xmlns:context="http://www.springframework.org/schema/context"

在xml中添加扫描的根目录

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

这样就将这些组件加入进来了。

1.<context:include-filter>子节点表示要包含的目标类
	注意:通常需要与 use-default-filters 属性配合使用才能够达到“仅包含某些 组件”这样的效果。即:通过将 use-default-filters 属性设置为 false, 禁用默认过滤器,然后扫描的就只是 include-filter 中的规则指定的 组件了。
2.<context:exclude-filter> 节点表示要排除在外的目标类 3.component-scan 下可以拥有若干个 include-filter 和 exclude-filter结点
类别示例说明
annotationcom.shang.XxxAnnotation过滤所有标注了 XxxAnnotation 的类。这个规则根 据目标组件是否标注了指定类型的注解进行过滤。
assignablecom.shang.BaseXxx过滤所有 BaseXxx 类的子类。这个规则根据目标组 件是否是指定类型的子类的方式进行过滤。
aspectjcom.shang.*Service+所有类名是以 Service 结束的,或这样的类的子类。 这个规则根据 AspectJ 表达式进行过滤。
regexcom.shang.anno.*所有 com.atguigu.anno 包下的类。这个规则根据正 则表达式匹配到的类名进行过滤。
customcom.shang.XxxTypeFilter使用 XxxTypeFilter 类通过编码的方式自定义过滤 规 则 。该 类 必 须 实 现 org.springframework.core.type.filter.TypeFilter 接口

三、使用@autowired注解实现根据类型自动装配

首先先创建三个MVC模式的类:

@Controller
public class BookServlet {

    @Autowired
    private BookService bookService;

    public void save() {
        bookService.save();
    }
}

@Service
public class BookService {
    @Autowired
    private BookDao bookDao;

    public void save() {
        System.out.println("正在调用bookDao.sava()");
        bookDao.sava();
    }
}

@Repository
public class BookDao {

    public void sava() {
        System.out.println("BookDao正在保存书--");
    }
}

在xml中进行这样的配置

<?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.shang"></context:component-scan>
</beans>

调用方法

ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans04.xml");
@Test
public void test01() {
    BookServlet bookServlet = applicationContext.getBean(BookServlet.class);
    bookServlet.save();
}

神奇的事情发生了,

正在调用bookDao.sava()
BookDao正在保存书--

成员类型被注入进来,而且没有使用set方法,这是一个很神奇的点,经过查阅资料发现。

在java的反射机制中,存在着这样一个方法setAccessible(boolean)方法,如果将其设置为true,我们就可以直接访问私有的成员,可以直接对这些值进行更改。

那么加了@Autowired注解后,Spring就自动将这个这个成员的访问控制检查关闭了,所有就不需要set()

四、资源类型的bean不止一个,autowired如何装配

@Autowired原理:

  • 先根据类型去容器中找到对应的组件
    • 找到一个,找到就赋值
    • 没有找到,抛异常
    • 找到多个,根据变量名作为id继续匹配

例子:

@Service
public class BookService {
    @Autowired
    private BookDao bookDao;

    public void save() {
        System.out.println("BookService");
        bookDao.sava();
    }
}
@Service
public class BookServiceExt extend BookService{
    @Autowired
    private BookDao bookDao;

    @Override
    public void save() {
        System.out.println("BookServiceExt---");
    }
}

1.第一次调用:注入BookService

 @Autowired
 private BookService bookService;

输出

BookService
BookDao正在保存书--

2.第二次调用,注入BookServiceExt

 @Autowired
 private BookServiceExt bookServiceExt;

输出

BookServiceExt---
BookDao正在保存书--

3.第三次调用,注入BookService,但是只将BookServiceExt放入容器

输出

BookServiceExt---
BookDao正在保存书--

4.@Qualifier自定义注入

此时可以在@Qualifier 注解里提供 bean 的名称。Spring 甚至允许在方法的形参上标注@Qualifiter 注解以指定注入 bean 的名称。

@Autowired
public void hahaha(@Qualifier("bookServiceExt")BookService bookservice) {
   System.out.println(bookservice);
}

五、@Autowired、@Resource和@Inject的区别

  • @Autowired注解: 最强大

  • @Resource: 注解 j2ee;java标准,扩展性更强。 要求提供一个 bean 名称的属性,若该属性为空,则自动采用标注处的 变量或方法名作为 bean 的名称。

  • @Inject: @Inject 和@Autowired 注解一样也是按类型注入匹配的 bean,但没有 reqired 属性。

标签:Autowired,Spring,BookService,bean,组件,注解,public
来源: https://blog.csdn.net/weixin_45483328/article/details/121635005

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有