首页 > 其他分享 >基于注解方式组件管理

基于注解方式组件管理

时间:2024-07-18 19:29:06浏览次数:10  
标签:基于 private public import 组件 注解 com class

基于注解方式组件管理

之前是通过在xml文件中向ioc容器中配置bean,通过<bean 标签的方式,注解的方式是在Java类上使用注解标记某个类,将该类配置到ioc容器。

主要分成两步:

  • 在类上使用注解

  • 让ioc识别那些类加了注解

1.注解的ioc配置

spring提供了以下几个注解,直接标记在类上,把他们定义成bean组件

  • @Component 该注解用于描述Spring中的bean,当一个类的功能不是controller、service、dao时,可以使用该注解

  • @Repository 该注解用于dao层的类

  • @Service 该注解用于 service层

  • @Controller 该注解用于 Controller层

package com.ztone.ioc_01.component;
​
import org.springframework.stereotype.Component;
​
@Component
public class HappyComponent {
}
​
@Controller
public class HappyController {
}

一个注解就相当于是一个bean标签,<bean id="happyController" class="HappyController"/>

后三个和@Component没有本质区别,只是能够清晰分辨类是哪一层的,在源码中后三个都使用了@Component来注解

image-20240715202726789

 

标记好类之后,在配置文件指定扫描哪个包下的注解,使用context:component-scan 标签

  • 第一种方式

    普通配置包扫描,context:component-scan 标签的 base-package属性指定ioc容器去那些包下查找注解类。该属性可以指定一个或多个包,多个包之间用逗号隔开,指定了父包相当于指定了该包内的所有子包

    <?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 https://www.springframework.org/schema/context/spring-context.xsd">
    ​
        <context:component-scan base-package="com.ztone.ioc_01"/>
    </beans>
  • 第二种

    扫描包后,可以排除某些注解,在context:component-scan 标签下,使用context:exclude-filter 标签来指定排除哪些注解,属性type是 annotation表示排除的类型是注解,expression是注解的全限定符

    <context:component-scan base-package="com.ztone.ioc_01">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
    </context:component-scan>
  • 第三种

    指定了扫描包后,指定只想要的注解,标签是 context:include-filter,需要在context:component-scan 注解加上 user-default-filter="false" 属性,表示指定包下的注解先不生效

    <context:component-scan base-package="com.ztone.ioc_01" user-default-filter="false" >
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>

 

Bean的name

在@Component、@Controller、@Service、@Repository 注解中可以使用value来指定该 组件的name

@Component(value = "happy")
public class HappyComponent {
}

如果只有一个value属性,那么value可以省略

在不指定value的情况时,组件的id就是 类名首字母小写

 

2.生命周期方法和作用域

通过注解指定生命周期方法

  • @PostConstruct 在初始化方法的上使用该注解

  • @PreDestroy 在销毁方法上使用该注解

指定bean的作用域使用的注解是 @Scope

注解中使用scopeName 属性指定是单例还是多例

  • ConfigurableBeanFactory.SCOPE_SINGLETION 单例,也是默认值

  • ConfigurableBeanFactory.SCOPE_PROTOTYPE 多例

@Component
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class JavaBean {
    
    @PostConstruct
    public void init(){
        
    }
    
    @PreDestroy
    public void destory(){
        
    }
}

 

 

3.注解的di配置

在一个组件中引用了另一个组件时,之前在xml中是通过在引用组件配置的标签内使用property 注入 被引用组件

现在直接在类中,引入属性的地方使用 @Autowired,进行自动装配。

@Controller
public class UserController {
    
    @Autowired
    private UserService userService;
}

不仅可以在成员变量上使用,还可用在构造方法和set方法上

@Autowired 的工作流程是:

  • 首先根据组件的类型进行装配

    • 如果能够找到唯一的bean则直接进行装配

    • 如果找不到则装配失败

  • 如果找到的bean 不止一个,那么就会根据成员变量的名字作为bean的id

    在这里可以使用 @Qualifier 来指定名称来作为 bean的id,如果没有指定,那么就会使用成员变量的变量名。

    public interface UserService {
        
    }
    ------
    @Service
    public class UserServiceImpl implements UserService{
    }
    ------
    @Service
    public class NewUserServiceImpl implements UserService{
        
    }

    现在有两个类都实现了 UserService 接口,在UserController 中还使用 接口去接收变量,属性名区分不开这两个类,就可以使用 @Qualifier

    @Controller
    public class UserController {
    
        @Autowired
        @Qualifier(value = "userServiceImpl")
        private UserService userService;
    }

    @Qulifier注解必须搭配 @Autowired使用,value的值,只能是属性的类型首字母小写或者是在@Component、@Conreoller...... 这种注解中指定的名字

Java提供了@Resource 注解,他的效果等同于 @Autowired + @Qulifier

要使用这个注解,在JDK版本高于11 或低于8 要引入依赖

@Controller
public class UserController {

    @Resource(value = "userServiceImpl")
    private UserService userService;
}

 

上面是引用类型的di配置,那么基本类型如何进行di配置呢?

使用的注解是 @Value

@Component
public class JavaBeanValue {
    
    @Value("zhangsan")
    private String name;
    
    private int age = 18;
    
}

一般基本类型都像age一样直接赋值。那么@Value 存在意义是什么呢?

@Value 可以读取文件中的数据

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

<context:property-placeholder location="classpath:information.properties"/>

首先扫描包下的注解,并且读取外部的配置文件

studentname=tom
studentpassword=123456

在@Value注解中 用 ${xxxx} 读取

@Value("zhangsan")
private String name;

private int age = 18;

@Value("${studentname}")
private String studentName;

@Value("${studentpassword}")
private String password;

如果读取不到还可以在后面用 :xxxx 指定默认值

@Value("${studentname:admin}") private String studentName;

 

4.三层架构案例注解实现

首先还是准备依赖,实体类,这些不再赘述,在实体类上用@Component注解

  1. 准备controller,service,dao层

    package com.ztone.controller;
    
    import com.ztone.pojo.Student;
    import com.ztone.service.StudentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    import java.util.List;
    
    @Controller
    public class StudentController {
    
        @Autowired
        private StudentService studentService;
    
        public void searchStudents(){
            List<Student> students = studentService.queryAllStudent();
            System.out.println(students);
        }
    }
    package com.ztone.service;
    
    import com.ztone.pojo.Student;
    
    import java.util.List;
    
    public interface StudentService {
        List<Student> queryAllStudent();
    }
    ------------------------------------
    package com.ztone.service;
    
    import com.ztone.dao.StudentDao;
    import com.ztone.pojo.Student;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    @Service
    public class StudentServiceImpl implements StudentService{
    
        @Autowired
        private StudentDao studentDao;
        @Override
        public List<Student> queryAllStudent() {
            return studentDao.queryAllStudent();
        }
    }
    package com.ztone.dao;
    
    import com.ztone.pojo.Student;
    
    import java.util.List;
    
    public interface StudentDao {
        List<Student> queryAllStudent();
    }
    --------------------------------
    package com.ztone.dao;
    
    import com.ztone.pojo.Student;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.BeanPropertyRowMapper;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public class StudentDaoImpl implements StudentDao{
        @Autowired
        private JdbcTemplate jdbcTemplate;
        @Override
        public List<Student> queryAllStudent() {
            String sql = "select id,name,gender,age,class as classes from students";
            List<Student> students = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Student.class));
            return students;
        }
    }

    这里使用到了注解 @Controller、@Service、@Repository在相应的类上,然后在注入属性的时候用到了 @Autowired注解

  2. 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.xsd">
    
    
    
        <context:property-placeholder location="classpath:jdbc.properties"/>
    
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="url" value="${url}"/>
            <property name="driverClassName" value="${driver}"/>
            <property name="username" value="${username1}"/>
            <property name="password" value="${password}"/>
        </bean>
    
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"/>
        </bean>
    
        <context:component-scan base-package="com.ztone"/>
    </beans>

    这个案例还是用 注解+xml的方式,自己定义的类用 注解注入到ioc容器,外部的类用xml方式

    使用注解不要忘记在xml中用 context:component-sacn 标签扫描包引入注解

     

遇到的问题:

扫描包要放在 引入 JdbcTemplate 后面,因为在StudentDao中用到了 JdbcTemplate,如果还没有将其注入ioc容器,就会报错。

标签:基于,private,public,import,组件,注解,com,class
From: https://www.cnblogs.com/wztblogs/p/18310296

相关文章

  • python gradio 的输出展示组件
    HTML:展示HTML内容,适用于富文本或网页布局。JSON:以JSON格式展示数据,便于查看结构化数据。KeyValues:以键值对形式展示数据。Label:展示文本标签,适用于简单的文本输出。Markdown:支持Markdown格式的文本展示。Plot:展示图表,如matplotlib生成的图表。Text:用于显示文本,适合较长的输出。......
  • 微信小程序开发中的第三方组件与插件使用
    微信小程序开发中,可以使用第三方组件和插件来扩展小程序的功能和性能。本文将结合代码案例,详细介绍第三方组件和插件的使用。一、第三方组件的使用引入第三方组件微信小程序开发者工具提供了「插件」功能,可以用来引入第三方组件。首先,在小程序的app.json文件中的"plugins"字......
  • 基于语音识别的会议记录系统
    目录核心功能页面展示使用技术方案功能结构设计数据库表展示核心功能页面展示视频展示功能1.创建会议在开始会议之前需要管理员先创建一个会议,为了能够快速开始会议,仅需填写会议的名称、会议举办小组、会议背景等简要会议信息即可成功创建。2.语音识别会议记录(最核心功......
  • 基于Python语言的入门算法和数据结构(持续更新中,求关注一波)[链表 栈 队列 复杂度 操作]
    这篇文章主要是讲的Python语言的算法,本人还在不断记笔记中,文章也会持续更新,内容比较浅薄,请大家指教另外推荐一个比较好用的记笔记的软件Typora,自己已经使用很久了,感觉不错。。。虽然但是还是有欠缺。目录第一章算法概述1.1什么是数据结构?01数据结构都有哪些组成方式02......
  • PiT : 基于池化层Pooling layer的Vision Transformer
        CNN的降维原理;随着深度的增加,传统CNN的通道维数增加,空间维数减少。经验表明,这样的空间降维对变压器结构也是有益的,并在原有的ViT模型的基础上提出了一种新的基于池的视觉变压器(PiT)。1.引言        ViT与卷积神经网络(CNN)有很大的不同。将输入图像......
  • 【YOLOv8改进-SPPF】 AIFI : 基于注意力的尺度内特征交互,保持高准确度的同时减少计算
    YOLOv8目标检测创新改进与实战案例专栏专栏目录:YOLOv8有效改进系列及项目实战目录包含卷积,主干注意力,检测头等创新机制以及各种目标检测分割项目实战案例专栏链接:YOLOv8基础解析+创新改进+实战案例介绍摘要YOLO系列因其在速度和准确性之间的合理权衡,成为了......
  • 重生归来,从 996福报 到 N+1告别职场【如何封装一个支持图片和PDF在线预览的Vue组件】
    如何封装一个支持图片和PDF在线预览的Vue组件在本文中,我将介绍如何设计并实现一个Vue组件,该组件能够在线预览图片和PDF文件。我们将基于element-ui的elImageViewer组件进行改造,并使用vue-pdf插件来实现PDF预览功能。本文将详细介绍从设计思路到落地实现的全过程,完整代码在......
  • AI Earth——基于决策树模型淮河流域冬小麦提取应用app
    应用介绍:本应用依据利用Landsat-8数据,基于潘力、夏浩铭、王瑞萌等研究论文(基于GoogleEarthEngine的淮河流域越冬作物种植面积制图)中提出的利用作物在不同物候期内卫星影像的光谱存在差异的特征,通过计算作物时间序列的皈依化植被指数(NDVI),选取越冬作物生长旺盛期NDVI最大......
  • 【Docker】基于Docker-compose创建LNMP环境
    目录一.Docker-compose概述1.容器编排管理与传统的容器管理的区别2.docker-compose作用3.docker-compose本质4.docker-compose的三大概念二.YML文件格式及编写注意事项1.yml文件是什么2.yml问价使用注意事项3.yml文件的基本数据结构三.Docker-compose配置1.Doc......
  • 基于MATLAB的从图像反演SAR原始回波【持续更新】
    一、概论当前在网上公开的SAR数据大部分都是聚焦过后的SLC图像,对想研究成像原理的朋友十分不友好,该文章提出了一种基于图像进行反演SAR原始回波的方法。二、SAR原理介绍想要理解SAR的原理,需要先了解两个基本概念1、多普勒效应多普勒效应(Dopplereffect)是为纪念奥地......