DAY03_Spring—自动装配注解模式优化XML文件

目录

  • 1 Spring注解模式
    • 1.1 自动装配
      • 1.1.1 说明
      • 1.1.2 配置规则
    • 1.2 注解模式
      • 1.2.1 关于注解的说明
      • 1.2.2 注解使用原理
      • 1.2.3 编辑配置文件
      • 1.2.4 属性注解
    • 1.3 实现MVC结构的纯注解开发
      • 1.3.1 编写java代码
      • 1.3.2 编辑xml配置文件
      • 1.3.3 编写测试类
      • 1.3.4 关于注解说明
      • 1.3.5 关于Spring工厂模式说明
    • 1.4 优化xml配置文件
      • 1.4.1配置类介绍
      • 1.4.2编辑配置类
      • 1.4.3 编辑测试代码
    • 1.5 Spring注解模式执行过程
    • 1.6 Spring中常见问题
      • 1.6.1 接口多实现类情况说明
      • 1.6.2 案例分析
    • 1.7 Spring容器管理业务数据@Bean注解
      • 1.7.1 @Bean作用
      • 1.7.2 编辑UserController
    • 1.8 Spring动态获取外部数据
      • 1.8.1 编辑properties文件
      • 1.8.2 编辑配置类

1 Spring注解模式

1.1 自动装配

1.1.1 说明

Spring基于配置文件 为了让属性(对象的引用)注入更加的简单.则推出了自动装配模式.

  • 根据名称自动装配
  • 根据类型自动装配

1.1.2 配置规则

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--1.构建user对象--><bean id="user" class="com.jt.pojo.User"><!--根据name属性查找对象的setId()方法 将value当作参数调用set方法完成赋值--><property name="id" value="100"/><!--<property name="name" value="&lt;范冰冰&gt;"/>--><property name="name"><value><![CDATA[<范冰冰>]]></value></property></bean><!--2.构建Dao对象根据面向接口编程Id:接口的名称class:实现类的包路径--><bean id="userDao" class="com.jt.dao.UserDaoImpl"/><!--3.构建Service自动装配: 程序无需手动的编辑property属性autowire="byName" 根据属性的名称进行注入1.找到对象的所有的set方法 setUserDao()2.setUserDao~~~~set去掉~~~UserDao~~~~首字母小写~~~userDao属性3.Spring会根据对象的属性查询自己维护的Map集合,根据userDao名称,查找Map中的Key与之对应,如果匹配成功.则能自动调用set方法实现注入(必需有set方法)autowire="byType"1.找到对象的所有的set方法 setUserDao()2.根据set方法找到方法中参数的类型UserDao.class3.Spring根据自己维护对象的Class进行匹配.如果匹配成功则实现注入(set方法)autowire:规则 如果配置了byName则首先按照name查找,如果查找不到则按照byType方式查找首选类型查找byType--><bean id="userService" class="com.jt.service.UserServiceImpl" autowire="byName"><!--<property name="userDao" ref="userDao"/>--></bean><!--4.构建Controller--><bean id="userController" class="com.jt.controller.UserController" autowire="byType"><!--<property name="userService" ref="userService"/><property name="user" ref="user"/>--></bean>
</beans>

1.2 注解模式

1.2.1 关于注解的说明

Spring为了简化xml配置方式,则研发注解模式.

Spring为了程序更加的严谨,通过不同的注解标识不同的层级 但是注解的功能一样

  • @Controller
    • 用来标识Controller层的代码 相当于将对象交给Spring管理
  • @Service
    • 用来标识Service层代码
  • @Repository
    • 用来标识持久层
  • @Component
    • 万用注解

1.2.2 注解使用原理

/*** <bean id="类名首字母小写~~userDaoImpl"  class="UserDaoImpl.class" />* 如果需要修改beanId则手动添加value属性即可*/
@Repository(value = "userDao")
public class UserDaoImpl implements UserDao{@Overridepublic void addUser(User user) {System.out.println("链接数据库执行insert into :"+user);}
}

1.2.3 编辑配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--1.构建user对象--><bean id="user" class="com.jt.pojo.User"><property name="id" value="100"></property><property name="name"><value><![CDATA[<范冰冰>]]></value></property></bean><!--2.让注解生效,开启包扫描包路径特点: 给定包路径,则自动扫描同包及子孙包中的类base-package: 根据指定的包路径 查找注解写方式: 多个包路径 使用,号分隔--><!--<context:component-scan base-package="com.jt.controller,com.jt.service,com.jt.dao"></context:component-scan>--><context:component-scan base-package="com.jt"></context:component-scan><!--业务需求1: 只想扫描@controller注解属性说明: use-default-filters="true"默认规则 :true  表示可以扫描其他注解:false  按照用户指定的注解进行加载,默认规则不生效--><context:component-scan base-package="com.jt" use-default-filters="false"><!--通过包扫描 不可以加载其他的注解 只扫描Controller注解--><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan><!--业务需求2: 不想扫描@controller注解--><context:component-scan base-package="com.jt"><!--通过包扫描 可以加载其他的注解 排除Controller注解--><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>
</beans>

1.2.4 属性注解

  • @Autowired: 可以根据类型/属性名称进行注入 首先按照类型进行注入如果类型注入失败,则根据属性名称注入
  • @Qualifier: 如果需要按照名称进行注入,则需要额外添加@Qualifier
  • @Resource(type = “xxx.class”,name=“属性名称”)
  • 关于注解补充:
    • 由于@Resource注解 是由java原生提供的,不是Spring官方的.所以不建议使用

上述的属性的注入在调用时 自动的封装了Set方法,所以Set方法可以省略不写

import com.jt.dao.UserDao;
import com.jt.pojo.User;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService{@Autowiredprivate UserDao userDao;//基于Spring注入dao  面向接口编程// public void setUserDao(UserDao userDao) {//     this.userDao = userDao;//}@Overridepublic void addUser(User user) {String name = user.getName() + "加工数据";user.setName(name);userDao.addUser(user);}
}

1.3 实现MVC结构的纯注解开发

1.3.1 编写java代码

public class User {//自动装配不能注入简单属性private Integer id;private String username;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +'}';}
}
import com.jt.pojo.User;public interface UserDao {void addUser(User user);
}
import com.jt.pojo.User;
import org.springframework.stereotype.Repository;@Repository
public class UserDaoImpl implements UserDao {@Overridepublic void addUser(User user) {System.out.println("新增用户的数据" + user);}
}
import com.jt.pojo.User;public interface UserService {void addUser(User user);
}
import com.jt.dao.UserDao;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Autowired //根据类型进行注入 如需要根据属性名称注入需要添加@Qualifier注解————必须按照名称进行匹配private UserDao userDao;@Overridepublic void addUser(User user) {userDao.addUser(user);}
}
import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {@Autowiredprivate UserService userService;public void addUser() {User user = new User();user.setId(101);user.setUsername("王昭君|不知火舞");userService.addUser(user);}
}

1.3.2 编辑xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--开启包扫描--><context:component-scan base-package="com.jt"/>
</beans>

1.3.3 编写测试类

@Testpublic void test01(){ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");UserController userController = context.getBean(UserController.class);userController.addUser();}
  • 测试结果

在这里插入图片描述

1.3.4 关于注解说明

  • 注解作用
    • 一些复杂的程序 以一种低耦合度的形式进行调用
  • 元注解:
    • @Target({ElementType.TYPE}) 标识注解对谁有效 type:类 method:方法有效
    • @Retention(RetentionPolicy.RUNTIME) 运行期有效(大)
    • @Documented 该注解注释编译到API文档中.
  • 由谁加载
    • 由Spring内部的源码负责调用.
      在这里插入图片描述

1.3.5 关于Spring工厂模式说明

  • Spring源码中创建对象都是采用工厂模式
    • 接口:BeanFactory(顶级接口)
  • Spring开发中需要手动的创建对象时
    • 一般采用 FactoryBean(业务接口)
  • 关于bean对象注入问题说明 一般需要检查注解是否正确配置
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.jt.service.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.jt.service.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

1.4 优化xml配置文件

1.4.1配置类介绍

随着软件技术发展,xml配置文件显得臃肿 不便于操作,所以Spring后期提出了配置类的思想

将所有的配置文件中的内容,写到java类中.

1.4.2编辑配置类

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration //标识我是一个配置类 相当于application.xml
@ComponentScan("com.jt") //如果注解中只有value属性 则可以省略
public class SpringConfig {}

1.4.3 编辑测试代码

@Testpublic void testAnno(){ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);UserController userController = context.getBean(UserController.class);userController.addUser();}
  • 测试结果

在这里插入图片描述

1.5 Spring注解模式执行过程

  1. 当程序启动Spring容器时 AnnotationConfigApplicationContext 利用beanFactory实例化对象
  2. 根据配置类中的包扫描开始加载指定的注解(4个). 根据配置文件的顺序依次进行加载
    在这里插入图片描述
  3. 当程序实例化Controller时,由于缺少Service对象,所以挂起线程 继续执行后续逻辑.
    当构建Service时,由于缺少Dao对象,所以挂起线程 继续执行后续逻辑.
    当实例化Dao成功时,保存到Spring所维护的Map集合中. 执行之前挂起的线程.
    所以以此类推 所有对象实现封装.最终容器启动成功
    在这里插入图片描述
  4. 根据指定的注解/注入指定的对象.之后统一交给Spring容器进行管理.最终程序启动成功.

1.6 Spring中常见问题

1.6.1 接口多实现类情况说明

Spring中规定 一个接口最好只有一个实现类.

  • 业务需求:
    • 要求给UserService接口提供2个实现类.

1.6.2 案例分析

  1. 编辑实现类A
    在这里插入图片描述
  2. 编辑实现类B
    在这里插入图片描述
  3. 实现类型的注入
import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;@Controller
public class UserController {/*** @Autowired: 首先根据属性的类型进行注入,* 如果类型不能匹配,则根据属性的名称进行注入.* 如果添加了@Qualifier("userServiceA") 则根据属性名称注入* 如果名称注入失败,则报错返回.*/@Autowired@Qualifier("userServiceB")private UserService userService;public void addUser() {User user = new User();user.setId(101);user.setUsername("王昭君|不知火舞");userService.addUser(user);}
}

1.7 Spring容器管理业务数据@Bean注解

1.7.1 @Bean作用

通过该注解,可以将业务数据实例化之后,交给Spring容器管理. 但是@Bean注解应该写到配置类中.

import com.jt.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration //标识我是一个配置类 相当于application.xml
@ComponentScan("com.jt") //如果注解中只有value属性 则可以省略
public class SpringConfig {/*1.Spring配置文件写法 <bean id="方法名称"  class="返回值的类型" />2.执行@Bean的方法 将方法名称当做ID,返回值的对象当做value 直接保存到Map集合中*/@Beanpublic User user(){User user = new User();user.setId(101);user.setUsername("Spring容器");return user;}
}

1.7.2 编辑UserController

import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;@Controller
public class UserController {/*** @Autowired: 首先根据属性的类型进行注入,* 如果类型不能匹配,则根据属性的名称进行注入.* 如果添加了@Qualifier("userServiceA") 则根据属性名称注入* 如果名称注入失败,则报错返回.*/@Autowired@Qualifier("userServiceA")private UserService userService;@Autowiredprivate User user;  //从容器中动态获取public void addUser() {userService.addUser(user);}
}
  • 测试结果

在这里插入图片描述

1.8 Spring动态获取外部数据

1.8.1 编辑properties文件

在这里插入图片描述

# 规则: properties文件
# 数据结构类型:  k-v结构
# 存储数据类型:  只能保存String类型
# 加载时编码格式: 默认采用ISO-8859-1格式解析 中文必然乱码
user.id=1001
# Spring容器获取的当前计算机的名称 所以user.name慎用
# user.name=你好啊哈哈哈
user.username=鲁班七号

1.8.2 编辑配置类

  • @PropertySource
    • 用法:
      • @PropertySource(“classpath:/user.properties”)
    • 说明:
      • @PropertySource 作用: 加载指定的pro配置文件 将数据保存到Spring容器中
  • @Value
    • java @Value(123) 将123值赋值给Id @Value("${user.id}") 在Spring容器中查找key=user.id的数据.通过${}语法获取
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;@Configuration //标识我是一个配置类 相当于application.xml
@ComponentScan("com.jt") //如果注解中只有value属性 则可以省略
//@PropertySource 作用: 加载指定的pro配置文件 将数据保存到Spring容器中
//encoding:指定字符集编码格式
@PropertySource(value = "classpath:/user.properties",encoding = "UTF-8")
public class SpringConfig {//定义对象属性 准备接收数据//@Value(123)   将123值赋值给Id//@Value("${user.id}")  在Spring容器中查找key=user.id的数据.通过${} 进行触发    @Value("${user.id}")@Value("${user.id}")private Integer id;@Value("${user.username}")private String username;/*1.Spring配置文件写法 <bean id="方法名称"  class="返回值的类型" />2.执行@Bean的方法 将方法名称当做ID,返回值的对象当做value 直接保存到Map集合中*/@Beanpublic User user(){User user = new User();user.setId(id);user.setUsername(username);return user;}
}
  • 测试结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/412167.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言之【函数】篇章以及例题分析

文章目录 前言一、函数是什么&#xff1f;二、C语言中函数的分类1、库函数2、自定义函数 三、函数的参数1、实际参数&#xff08;实参&#xff09;2、形式参数&#xff08;形参&#xff09; 四、函数的调用1、传值调用2、传址调用3、专项练习3.1 素数判断3.2 闰年判断3.3 二分查…

【Spring源码分析】从源码角度去熟悉依赖注入(一)

从源码角度去熟悉依赖注入 一、全局出发引出各种依赖注入策略二、Autowired依赖注入源码分析属性注入源码分析&#xff08;AutowiredFieldElement.inject&#xff09;方法注入源码分析&#xff08;AutowiredMethodElement.inject&#xff09;流程图 其实在上篇阐述非懒加载单例…

手拉手Vue组件由浅入深

组件 (Component) 是 Vue.js 最强大的功能之一&#xff0c;它是html、css、js等的一个聚合体&#xff0c;封装性和隔离性非常强。 组件化开发&#xff1a; 1、将一个具备完整功能的项目的一部分分割多处使用 2、加快项目的进度 3、可以进行项目的复用 组件注册分…

android studio使用总结

gradle是项目构建的工具&#xff0c;在gradle-wrapper.properties这个文件中设置&#xff0c; 然后就会下载相应版本的安装包到这个路径C:\Users\ly.gradle\wrapper\dists&#xff0c;例如这里是7.0.2&#xff0c; gradle和studio中的jdk版本需要对应&#xff0c;否则无法构建项…

khbc靶场小记(upload 666靶场)

尝试上传正常的png jpg gif php的格式的文件发现老是提示烦人的消息&#xff08;上传不成功&#xff09;&#xff1b; 通过抓包对MIME进行爆破没爆出来&#xff0c;当时可能用成小字典了&#xff1b; 猜测可能是把后缀名和MIME绑定检测了&#xff1b; 反正也没思路&#xff0c;…

lombok引发的血案

一直以为lombok是一个无比牛叉的省代码工具&#xff0c;感觉再也不用&#xff0c;好爽&#xff1b; 然而lombok再给我们带来便利的同时&#xff0c;却有可能悄无声息的带来各种代码问题&#xff1b; 今天笔主就遇到了一个引发生产事故的bug&#xff1b; 我们在开发后端项目时…

C++核心编程之通过类和对象的思想对文件进行操作

目录 ​​​​​​​一、文件操作 1. 文件类型分类&#xff1a; 2. 操作文件的三大类 二、文本文件 1.写文件 2.读文件 三、二进制文件 1.写二进制文件 2.读二进制文件 一、文件操作 程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放 通过文件可以将…

qt.qpa.plugin: Could not find the Qt platform plugin “windows“ in ““

系统环境&#xff1a;Win10家庭中文版 Qt : 5.12.9 链接了一些64位的第三方库&#xff0c;程序编译完运行后出现 qt.qpa.plugin: Could not find the Qt platform plugin "windows" in "" 弹窗如下&#xff1a; 网上搜了一些都是关于pyQt的&#xff0c…

.Net Core 使用 AspNetCoreRateLimit 实现限流

上一篇文章介绍过ASP.NET Core 的 Web Api 实现限流 中间件-CSDN博客 使用.NET 7 自带的中间件 Microsoft.AspNetCore.RateLimiting 可以实现简单的Api限流&#xff0c;但是这个.NET 7以后才集成的中间件&#xff0c;如果你使用的是早期版本的.NET&#xff0c;可以使用第三方库…

10个用于Android开发的有用的Kotlin库及示例

10个用于Android开发的有用的Kotlin库及示例 在Android开发领域&#xff0c;Kotlin已成为一门领先的语言&#xff0c;带来了现代语法和功能的浪潮。随着Kotlin的崛起&#xff0c;涌现出了许多专为其定制的库&#xff0c;进一步增强了开发体验。本文将深入介绍其中的10个库&…

C#中的文件操作

为什么要对文件进行操作&#xff1f; 在计算机当中&#xff0c;数据是二进制的形式存在的&#xff0c;文件则是用于存储这些数据的单位&#xff0c;因此在需要操作计算机中的数据时&#xff0c;需要对文件进行操作。 在程序开发过程中&#xff0c;操作变量和常量的时候&#…

Dockerfile镜像实战

目录 一 构建SSH镜像 1.开启ip转发功能 2. 准备工作目录 3.修改配置文件 5.启动容器并修改root密码 二 构建Systemctl镜像 1. 准备工作目录 ​编辑2.修改配置文件 3.生成镜像 4.启动容器&#xff0c;并挂载宿主机目录挂载到容器中&#xff0c;进行初始化 5.进入容器 三…