Spring02

使用 spring 的 IoC 的实现账户的CRUD

1.环境搭建

创建 maven 工程并导入坐标

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>com.zaxxer</groupId>
      <artifactId>HikariCP</artifactId>
      <version>3.4.5</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.46</version>
    </dependency>
    <dependency>
      <groupId>commons-dbutils</groupId>
      <artifactId>commons-dbutils</artifactId>
      <version>1.7</version>
    </dependency>

创建数据库和编写实体类

sql

create table account(
id int primary key auto_increment, name varchar(40),
money float
)character set utf8 collate utf8_general_ci;

insert into account(name,money) values('aaa',1000); insert into account(name,money) values('bbb',1000); insert into account(name,money) values('ccc',1000);

pojo
在这里插入图片描述

编写持久层代码

持久层
在这里插入图片描述

编写业务层代码

service
在这里插入图片描述

创建配置文件并导入约束

beans.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
        <property name="password" value="root"/>
        <property name="username" value="root"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///day05?characterEncoding=utf-8"/>
    </bean>

    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>

    <bean id="accountService" class="top.baivip.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>
    </bean>

    <bean id="accountDao" class="top.baivip.dao.imp.AccountDaoImpl">
        <property name="queryRunner" ref="queryRunner"/>
    </bean>
</beans>

测试

测试
在这里插入图片描述
在获取的时候可以获取类型来返回对象
在这里插入图片描述

基于注解的 IOC 配置

学习基于注解的 IoC 配置,大家脑海里首先得有一个认知,即注解配置和 xml 配置要实现的功能都是一样的,
都是要降低程序间的耦合。只是配置的形式不一样。
关于实际的开发中到底使用 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:component-scan base-package="top.baivip"></context:component-scan>

1. 常用注解

1.1 用于创建对象的

相当于:<bean id="" class="">

@Component

可以不用写set,原理暴力反射
在这里插入图片描述
在这里插入图片描述

@Controller @Service @Repository
他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。他们只不过是提供了更加明确的语义化。
@Controller:一般用于表现层的注解。
@Service:一般用于业务层的注解。
@Repository:一般用于持久层的注解。
细节:如果注解中有且只有一个属性要赋值时,且名称是 value,value 在赋值是可以不写。

1.2 用于注入数据的

相当于: <property name="" ref=""> <property name="" value="">

@Resource

在这里插入图片描述
Resource里可以写类型
在这里插入图片描述

@Autowired

在这里插入图片描述

@Qualifier(必须和Autowired一起用)
作用:
在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和
@Autowire 一起使用;但是给方法参数注入时,可以独立使用。
属性:
value:指定 bean 的 id。

在这里插入图片描述
@Resource==@Autowired@Qualifier

@Value
	作用:
		注入基本数据类型和 String 类型数据的
	属性:
		value:用于指定值

1.3 用于改变作用范围的

相当于:<bean id="" class="" scope="">

@Scope
	作用:
		指定 bean 的作用范围。
	属性:
		value:指定范围的值。
		取值:singleton prototype request session globalsession

1.4 和生命周期相关的:(了解)

`相当于:

@PostConstruct
	作用:
	  用于指定初始化方法。
@PreDestroy
	作用:
	  用于指定销毁方法。

在这里插入图片描述

关于 Spring 注解和 XML 的选择问题

在这里插入图片描述

2. 引入外部文件

2.1 第一种方式

准备工作

 <!--
        引入外部属性文件
        可以引入多个 ,分割
    -->
<context:property-placeholder location="classpath:db.properties,classpath:foo.properties"></context:property-placeholder>
   <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
        <property name="password" value="${jdbc.password}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
    </bean>

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///day05?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

2.2 第二种方式

不只是配置数据库,也可以配置属性
xml配置
beans.xml

<bean id="messageUtil" class="com.itheima.utils.MessageUtil">
        <property name="username" value="${foo.name}"></property>
        <property name="password" value="${foo.password}"></property>
</bean>

foo.properties

#TODO 待解释
#在java原因中  properties文件 中文必须进行unicode转换
foo.name=\u5c0f\u660e
foo.password=123

注解配置
在这里插入图片描述

3. 半注解半xml

Test.java
在这里插入图片描述
Beans.xml
在这里插入图片描述
Service.java
在这里插入图片描述
Dao.java
在这里插入图片描述

4. Spring纯注解

4.1 spring 的纯注解配置

写到此处,基于注解的 IoC 配置已经完成,但是大家都发现了一个问题:我们依然离不开 spring 的 xml 配置文件,那么能不能不写这个 bean.xml,所有配置都用注解来实现呢?
当然,同学们也需要注意一下,我们选择哪种配置的原则是简化开发和配置方便,而非追求某种技术。

4.2 待改造的问题

在这里插入图片描述

4.3 新注解说明

@Configuration
	作用:
		用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用
AnnotationApplicationContext(有@Configuration 注解的类.class)。
	属性:
   value:用于指定配置类的字节码示例代码:
	/**
	*	spring 的配置类,相当于 bean.xml 文件
	*	@author 黑马程序员
	*	@Company http://www.ithiema.com
	*	@Version 1.0
	*/
	@Configuration
	public class SpringConfiguration {
	}
注意:
我们已经把配置文件用类来代替了,但是如何配置创建容器时要扫描的包呢? 请看下一个注解。
@ComponentScan
	作用:
		用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:
		<context:component-scan base-package="com.itheima"/>是一样的。
	属性:
		basePackages:用于指定要扫描的包。和该注解中的 value 属性作用一样。示例代码:
	/**
	*	spring 的配置类,相当于 bean.xml 文件
	*	@author 黑马程序员
	*	@Company http://www.ithiema.com
	*	@Version 1.0
	*/
	@Configuration
	@ComponentScan("com.itheima")
	public class SpringConfiguration {
		}
	注意:
		我们已经配置好了要扫描的包,但是数据源和 QueryRuner 对象如何从配置文件中移除呢? 请看下一个注解。
@Bean
	作用:
		该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。
	属性:
		name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)。
@PropertySource
	作用:
		用于加载.properties 文件中的配置。例如我们配置数据源时, 可以把连接数据库的信息写到properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。
	属性:
		value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:
@Import
	作用:
		用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。当然,写上也没问题。
	属性:
		value[]:用于指定其他配置类的字节码。示例代码:
		@Configuration
		@ComponentScan(basePackages = "com.itheima.spring")
		@Import({ JdbcConfig.class})
		public class SpringConfiguration {
	}
	
		@Configuration//写不写都行
		@PropertySource("classpath:jdbc.properties")
		public class JdbcConfig{
		}
	注意:
	我们已经把要配置的都配置好了,但是新的问题产生了,由于没有配置文件了,如何获取容器呢? 请看下一小节。
通过注解获取容器:
ApplicationContext ac =
new AnnotationConfigApplicationContext(SpringConfiguration.class);

4.4 示例

Config.java

/*
*
* Configuration 注解作用标明 该类是一个配置类
*
*
* */
@Configuration
/**
 * 等同于你在配置中
 *  <context:component-scan base-package="包名"></context:component-scan>
 */
@ComponentScan({"com.itheima.service","com.itheima.dao","com.itheima.domain"})
/**
 * 引入其他的配置类的  目的就是拆分 就是清晰明了
 */
@Import({DaoConfig.class,UtilConfig.class})

public class Config {
    
}

DaoConfig.java

/*
 *
 * Configuration 注解作用标明 该类是一个配置类
 *
 *
 * */
@Configuration
/**
 * 等同于你在配置中
 *  <context:component-scan base-package="包名"></context:component-scan>
 */
@ComponentScan({"com.itheima.dao"})
/**
 * 等同于你在配置文件中写的
 * <context:property-placeholder location="你的配置文件地址"></context:property-placeholder>
 */
@PropertySource("classpath:db.properties")
public class DaoConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    /**
     * 含义  当spring框架已注解方式启动 扫描配置类 方法
     * 如果方法有@Bean注解  那么意思就是 将该方法返回值 放入spring容器中
     * 作用等同于 <bean id=""></bean>
     * //一般情况下 都懒得写名字
     * @return
     */
    //@Bean("qr")
    @Bean
    public QueryRunner getQueryRunner(@Qualifier("dataSource2") DataSource dataSource){

        QueryRunner queryRunner = new QueryRunner(dataSource);

        return queryRunner;
    }

    @Bean("dataSource1")
    public DataSource getDataSource1(){
        HikariDataSource hikariDataSource = new HikariDataSource();
        hikariDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        hikariDataSource.setJdbcUrl("jdbc:mysql:///heima349?characterEncoding=utf-8");
        hikariDataSource.setUsername("root");
        hikariDataSource.setPassword("123");
        return hikariDataSource;
    }
    @Bean("dataSource2")
    public DataSource getDataSource2(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driver);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        return druidDataSource;
    }

Spring 整合 Junit[掌握]

问题

在这里插入图片描述

解决思路分析

针对上述问题,我们需要的是程序能自动帮我们创建容器。一旦程序能自动为我们创建 spring 容器,我们就无须手动创建了,问题也就解决了。
我们都知道,junit 单元测试的原理(在 web 阶段课程中讲过),但显然,junit 是无法实现的,因为它自己都无法知晓我们是否使用了 spring 框架,更不用说帮我们创建 spring 容器了。不过好在,junit 给我们暴露了一个注解,可以让我们替换掉它的运行器。
这时,我们需要依靠 spring 框架,因为它提供了一个运行器,可以读取配置文件(或注解)来创建容器。我们只需要告诉它配置文件在哪就行了。

实例

第一步:导入 spring 整合 Junit 的坐标

此处需要注意的是,spring5 及以上版本要求 junit 的版本必须是 4.12 及以上,否则用不了。
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.1.7.RELEASE</version>
</dependency>

第二步:使用@RunWith 注解替换原有运行器

/**
*	测试类
*	@author 黑马程序员
*	@Company http://www.ithiema.com
*	@Version 1.0
*/
	@RunWith(SpringJUnit4ClassRunner.class) 
	public class AccountServiceTest {
	}

第三步:使用@ContextConfiguration 指定 spring 配置文件的位置

/**
*	测试类
*	@author 黑马程序员
*	@Company http://www.ithiema.com
*	@Version 1.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"classpath:bean.xml"})
public class AccountServiceTest {
}



@ContextConfiguration 注解:
locations 属性:用于指定配置文件的位置。如果是类路径下,需要用 classpath:表明
classes 属性:用于指定注解的类。当不使用 xml 配置时,需要用此属性指定注解类的位置。	

实例

在这里插入图片描述

为什么不把测试类配到 xml 中

在解释这个问题之前,先解除大家的疑虑,配到 XML 中能不能用呢? 答案是肯定的,没问题,可以使用。
那么为什么不采用配置到 xml 中的方式呢?
这个原因是这样的:
第一:当我们在 xml 中配置了一个 bean,spring 加载配置文件创建容器时,就会创建对象。
第二:测试类只是我们在测试功能时使用,而在项目中它并不参与程序逻辑,也不会解决需求上的问题,所以创建完了,并没有使用。那么存在容器中就会造成资源的浪费。
所以,基于以上两点,我们不应该把测试配置到 xml 文件中。

最后总结

如果想要往 spring容器中注入对象

注解的方式:


    在类上加注解
    @component("名字") 作用等于 配置中 bean 名字=id
    当然也可以更加的明确说明
    @Controller 指明servlet层的对象
    @Service 指明是service对象
    @Repository 指明是dao对象
    上面注解只是给我们人看的

    并且三个注解可以给对象起名 如果你懒 不想给名字 不写  默认注入到spring容器的名字就是类名  首字母小写

    @Resource()
    用来从spring容器获取对象 注入对象属性
    @Resource(name="",type=类型)
    两者皆可以  都不用

    @AutoWired 替代@Resource 更加简单






      使用spring对于junit测试支持
        注解方式
        @ContextConfig(location="配置文件地址")

    但是 注意 不管是用resource 还是autoWired 都有限制 当你根据类型注入 一定要保证 在容器中 只有一个该类型的对象
    但是在我们正常开发 其实很少会写俩个实现类 一般都是用autoWired 就是因为省事


    但是一切的前提 在配置中 告诉人家 你的类在哪个包下

    以后开发中 常用注解 就两个
    @Service
    @AutoWired

    更加没有用的的注解
    @Qualifier  唯一指明的
    用来配合autoWired autoWired根据类型匹配 一旦发现 某个类型多个实现类 可以使用Qualifier 指明名字
    基本不用  如果一旦有多个 用@resource 指明名字



    注入一些外部的properties属性文件
    首先在配置文件
    <context:property-placeholder location="classpath:db.properties,classpath:foo.properties"></context:property-placeholder>

    location指明文件的路径  classpath:  翻译类路径的意思
    多个可以逗号隔开

    在对象中要使用的话 可以采用@Value("${写在properties的属性名}")
使用纯注解开发:
    1.创建容器
    new AnnotationConfigApplicationContext();

    2.如果对象自己写 我们使用 @Servcie @repsitory 放入容器
    前提 写 配置类
    配置类写法:
        随便一个类  加注解
        @Configuration
        希望扫描包
        @ComponentScan({"com.itheima.service","com.itheima.dao"})

    3.如果使用别人第三方jar中对象 无法往人家类加@Service @component
    只需要写一个方法 方法叫啥无所谓
    返回值就是想要对象
    并且加上注解 @Bean  如果起名给个名字 不想就拉倒


    注解式引入外部属性文件

    需要配置类上加一个注解
    @PropertySource("classpath:db.properties")

    然后类中写属性
    @Value("属性名") 注入到对象中
    


    注解式的配置类 可以拆分的
    多写几个配置类 配置类地代码都一样

    在主配置类通过 @Import 吧其他的配置 包含进来




    使用spring对于junit测试支持
    注解方式
    @ContextConfig(class=配置类.class)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值