【Spring】IocDI详解(6)

本系列共涉及4个框架:Sping,SpringBoot,Spring MVC,Mybatis。

博客涉及框架的重要知识点,根据序号学习即可。

有什么不懂的都可以问我,看到消息会回复的,可能会不及时,请见谅!!

目录

本系列共涉及4个框架:Sping,SpringBoot,Spring MVC,Mybatis。

博客涉及框架的重要知识点,根据序号学习即可。

1、前言

1.1 Spring具体概念

1.2 什么是容器呢?

1.3 什么是IoC

2、IoC详解

2.1 什么是IoC

2.2 IoC有什么作用

2.3 IoC有什么优势

2.4 IoC的使用

2.5 Bean的存储【非常重要!!!一定要好好理解】

2.5.1 @Controller(控制器存储)

2.5.2 @Service(服务存储)

2.5.3 @Repository(仓库存储)

2.5.4 @Component (组件存储)

2.5.5 @Configuration(配置存储)

2.5.6 @Bean 【方法注解---唯一的】

2.6 注解之间的关系

3、DI详解

3.1 什么是DI

3.2 DI与IoC的联系

3.3 DI的使用

3.4 依赖注入的三种方式

3.4.1 属性注入

3.4.2 构造方法注入

3.4.3 Setter注入(设值注入)

3.5 三种注入的优缺点

3.6 @Autowired存在的问题


1、前言

1.1 Spring具体概念

之前的文章谈及到什么是Spring,但是只给了一个抽象的定义。目前我们知道Spring是一个开源的框架,它让我们的开发更加简单,也支持广泛的应用场景,有着活跃而庞大的社区,这也是Spring长久不衰的原因。由于对Spring有着模糊的了解,现在给出一个更加具体的概念:Spring是一个包含众多工具的Ioc容器【关键词:容器??Ioc??】

1.2 什么是容器呢?

容器是用来容纳某种物品的装置。其实在开发圈子,容器这个词已经用得泛滥了。

之前我们遇到过什么容器呢?

List/Map——>数据存储容器

Tomcat——>web容器

1.3 什么是IoC

Ioc是Spring的核心思想【Spring两大核心思想:Ioc与Aop(后续会写关于Aop的文章)】。

其实IoC在之前将Spring MVC入门的文章已经用过了,在类上面添加@RestController和@Controller注解,就是把这个对象交给Spring管理,Spring框架启动时就会加载该类,把对象交给Spring管理,就是IoC思想。




2、IoC详解

2.1 什么是IoC

(1)IoC:Inversion of Control(控制反转),也就是说Spring是一个"控制反转"的容器。

(2)什么是控制反转呢?也就是控制权反转。什么的控制权发生反转?获得依赖对象的过程被反转了,也就是说,当需要某个对象时,传统开发模式中需要自己new创建对象,现在不需要再进行创建,把创建对象的任务交给容器,程序中只需要依赖注入(Dependency Injection,DI)就可以了。这个容器称为:IoC容器。Spring是一个IoC容器,所以有时Spring也称Spring 容器。

2.2 IoC有什么作用

        使用IoC思想是将控制权进行反转,简而言之就是不再是使用方对象创建并控制依赖对象了,而是把依赖对象注入当前对象中,依赖对象的控制权不再由当前类控制了。这样的话,即使依赖类发生任何改变,当前类是不受影响的,这就是典型的控制反转,也是IoC的实现思想。

2.3 IoC有什么优势

资源不由使用资源的双方管理,而是由不使用资源的第三方管理,可以带来一下好处:

(1)资源集中管理:IoC容器会帮助我们管理一些资源(对象等),需要使用时直接从IoC容器中去取

(2)同时在创建实例的时候不需要了解其中的细节,降低了使用资源双方的依赖程度,以达软件设计原则中的“低耦合”

Spring就是一种IoC容器,帮助我们管理资源

2.4 IoC的使用

(1)既然Spring是一个IoC(控制反转)容器,那么作为容器,它的基本功能就是存和取

(2)Spring容器管理的主要是对象,我们称这些对象为“Bean”。我们把这些“Bean”交给Spring管理,由Spring来负责对象的创建和销毁,我们程序只需要告诉Spring,哪些需要存,以及哪些需要从Spring中取出来。Spring创建及管理对象就是Bean的存储【非常重要!!!】

2.5 Bean的存储【非常重要!!!一定要好好理解】

要把某个对象交给IoC容器管理,需要在类之前加上注解@Component,而Spring框架为了更好的服务web应用程序,提供了更丰富的注解。

共有两类注解类型可以使用:

1、类注解:@Controller、@Service、@Repository、@Component、@Configuration

2、方法注解:@Bean

2.5.1 @Controller(控制器存储)

(1)使用@Controller存储Bean的代码如下:

@Controller
public class UserController {public void sayHi(){System.out.println("hi,UserController");}
}

如何观察这个对象已经存在Spring容器当中了呢?

接下来学习如何从Spring容器中获取对象

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象UserController userController=context.getBean(UserController.class);//使用对象userController.sayHi();}
}

 ApplicationContext翻译过来就是Spring上下文。因为对象都交给Spring管理了,所以获取对象要从Spring中取,那么就需要先得到Spring上下文。当前这个上下文是指当前的运行环境,也可以看做是一个容器,容器里面存了很多内容,这个内容是当前的运行环境。

(2)Bean命名约定

程序人员不需要为bean指定名称,就是说如果没有显式的提供名称,Spring容器会为bean生成唯一的名称。

命名约定使用Java标准约定作为实例字段名,也就是说,bean名称使用小驼峰的形式,比如类名为UserController的Bean的名称为userController

当然也会有一些特殊情况就是当多个字符并且第一个和第二个字母都是大写时,将保留原始大小写。比如类名为UController的Bean的名称为UController

(3)获取Bean的其他方式

如果Spring容器中,同一个类型存在多个Bean的话,怎么获取呢?ApplicationContext也提供了其他获取Bean的方式,ApplicationContext获取Bean对象的功能,是父类BeanFactory提供的功能

@SpringBootApplication
public class SpringIocApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//根据bean的类型,从上下文中获取对象UserController userController1=context.getBean(UserController.class);//根据bean的名字,从上下文中获取对象UserController userController2=(UserController) context.getBean("userController");//根据bean的类型+名字,从上下文中获取对象UserController userController3=context.getBean("userController", UserController.class);System.out.println(userController1);System.out.println(userController2);System.out.println(userController3);}
}

地址都一样,说明是同一个对象

2.5.2 @Service(服务存储)

使用@Service存储Bean的代码如下:

@Service
public class UserService {public void sayHi(){System.out.println("hi,UserService");}
}

获取bean的代码 

@SpringBootApplication
public class SpringIocApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class);//从上下文中获取对象UserService userServicer=context.getBean(UserService.class);//使用对象userService.sayHi();}
}

2.5.3 @Repository(仓库存储)

使用@Repository存储Bean的代码如下:

@Repository   //将对象存储到Spring中
public class UserRepository {public void say(){System.out.println("hi,UserRepository");}
}

获取bean的代码

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象UserRepository userRepository=context.getBean(UserRepository.class);//使用对象userRepository.sayHi();}
}

2.5.4 @Component (组件存储)

使用@Component存储Bean的代码如下:

@Component
public class UserComponent {public void sayHi(){System.out.println("hi,UserComponent");}
}

获取bean的代码

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象UserComponent userComponent=context.getBean(UserComponent.class);//使用对象userComponent.sayHi();}
}

 

2.5.5 @Configuration(配置存储)

使用@Configuration存储Bean的代码如下:

@Configuration
public class UserConfiguration {public void sayHi(){System.out.println("hi, UserConfiguration");}
}

获取bean的代码

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象UserConfiguration userConfiguration=context.getBean( UserConfiguration .class);//使用对象userConfiguration.sayHi();}
}

2.5.6 @Bean 【方法注解---唯一的】

在某些外部包的类无法使用类注解以及某些类需要多个对象,这个时候需要使用方法注解@Bean

(1)方法注解需要配合类注解使用

import lombok.Data;@Data
public class User {private String name;private int age;
}
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class BeanConfig {@Beanpublic User user(){User user=new User();user.setName("zhangsan");user.setAge(18);return user;}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象User user=context.getBean(User.class);//使用对象System.out.println(user);}
}

 

(2)定义多个对象

①根据类型获取user时,报错显示:期望只有一个匹配,却发现了两个,user1和user2

@Component
public class BeanConfig {@Beanpublic User user1(){User user=new User();user.setName("zhangsan");user.setAge(18);return user;}@Beanpublic User user2(){User user=new User();user.setName("lisi");user.setAge(17);return user;}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象User user=context.getBean(User.class);//使用对象System.out.println(user);}
}

②根据名称来获取bean对象

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象User user1= (User) context.getBean("user1");User user2= (User) context.getBean("user2");//使用对象System.out.println(user1);System.out.println(user2);}
}

(3)重命名Bean

可以通过设置name属性给Bean对象进行重命名。此时我们使用u1就可以获取到User对象了

@Component
public class BeanConfig {@Bean(name = {"u1","user1"})public User user1(){User user=new User();user.setName("zhangsan");user.setAge(18);return user;}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象User u1= (User) context.getBean("u1");//使用对象System.out.println(u1);}
}

2.6 注解之间的关系

(1)为什么有这么多类注解

这个也是和应用分层相呼应的,让开发人员看到类注解之后,就能直接了解当前类的用途。

@Controller:控制层,接受请求,对请求进行处理,并进行响应

@Service:业务逻辑层,处理具体的业务逻辑

@Repository:数据访问层,也称辞旧层,负责数据访问操作

@Configuration:配置层。处理项目中的一些配置信息。

(2)类注解之间的关系

查看@Controller/@Service/@Repository/@Configutation 等注解的源码发现,这些注解里面都有一个注解@Component,说明它们本来就是属于@Component的子类。@Component是一个元注解,就是也可注解其他类的注解,@Controller/@Service/@Repository/@Configutation等,这些注解都被称为@Component的衍生注解。




3、DI详解

3.1 什么是DI

        DI:Dependency Injection(依赖注入)。容器在运行期间,动态的为应用程序提供运行时所依赖的资源,称之为依赖注入。

3.2 DI与IoC的联系

(1)程序运行时需要某个资源,此时容器就为其提供这个资源。从这点可以看出,依赖注入(DI)与控制反转(IoC)是从不同的角度的描述的同一件事,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象间的解耦。

(2)IoC是一种思想,也是一种“目标”,而思想只是一种指导原则,最终还是需要有可行的落地方案,而DI就是属于具体的实现,所以,DI是IoC的一种实现

3.3 DI的使用

依赖注入是一个过程,是指IoC容器在创建Bean时,去提供运行时所依赖的资源,而资源指的就是对象。

3.4 依赖注入的三种方式

3.4.1 属性注入

属性注入式使用@Autowired实现的,将Service类注入到Controller类中

Service类的实现代码:

import org.springframework.stereotype.Service;@Service
public class UserService {public void sayHi(){System.out.println("hi,UserService");}
}

Controller类的实现代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {//1、属性注入@Autowiredprivate UserService userService;public void sayHi(){System.out.println("hi,UserController");userService.sayHi();}
}

获取Controller中的sayHi方法

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象UserController userController=context.getBean(UserController.class);//使用对象userController.sayHi();}
}

3.4.2 构造方法注入

构造方法是在类的构造方法中实现注入的

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController2 {//2、构造方法注入private UserService userService;@Autowiredpublic UserController2(UserService userService){this.userService=userService;}public void sayHi(){System.out.println("hi,UserController2");userService.sayHi();}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象UserController2 userController2=context.getBean(UserController2.class);//使用对象userController2.sayHi();}
}

 

PS:如果类只有一个构造方法,那么@Autowired注解可以省略;如果类中又多个构造方法时,那么需要添加上@Autowired来明确指定到底使用哪个构造方法

3.4.3 Setter注入(设值注入)

Setter注入和属性的setter方法实现类似,只不过在设置set方法的时候加上@Autowired注解

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController3 {//2、Setter注入private UserService userService;@Autowiredpublic void setUserController3(UserService userService){this.userService=userService;}public void sayHi(){System.out.println("hi,UserController3");userService.sayHi();}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取Spring上下文ApplicationContext context=SpringApplication.run(DemoApplication.class,args);//从Spring上下文中获取对象UserController3 userController3=context.getBean(UserController3.class);//使用对象userController3.sayHi();}
}

3.5 三种注入的优缺点

(1)属性注入

优点:简洁,使用方便

缺点:只能用于IoC容器;不能注入一个final修饰的属性

(2)构造方法

优点:可以注入final修饰的属性;注入的对象不会被修改;依赖对象在使用前一定会被完全初始化,因为依赖是在类的构造方法中执行的,而构造方法是在类的加载阶段就会执行的方法;通用性好,构造方法是JDK支持的,所以更换任何框架,也是适用的。

缺点:注入多个对象时,代码会比较繁琐

(3)setter注入

优点:方便在类的实例之后,重新对该对象进行配置或者注入

缺点:不能注入一个final修饰的属性;注入对象可能会被改变,因为setter方法可能会被多洗调用,就会用被修改的风险

3.6 @Autowired存在的问题

(1)同一类型存在多个bean时,使用@Autowired会报错。报错的原因是,非唯一的Bean对象。上面已经出现过了

(2)解决方法:使用以下注解

@Primary、@Qualifier、@Resource

①使用@Primary注解:当存在多个相同类型的Bean注入时,加上@Primary注解,用来确定默认的实现

@Component
public class BeanConfig {@Primary  //指定该bean为默认的bean@Beanpublic User user1(){User user=new User();user.setName("zhangsan");user.setAge(18);return user;}@Beanpublic User user2(){User user=new User();user.setName("lisi");user.setAge(17);return user;}
}

②使用@Qualifier注解,指定当前要注入的bean对象。在@Qualifier的value属性中,指定注入的bean的名称【@Qualifier注解不可以单独使用,必须配合@Autowired使用】

@Controller
public class UserController {@Qualifier("user1")  //指定bean的名称@Autowiredprivate User user;public void sayHi(){System.out.println("hi,UserController");System.out.println(user);}
}

③使用@Resource注解,是按照bean的名称进行注入。通过name属性指定要注入的bean的名称

@Controller
public class UserController {@Resource(name = "user1")private User user;public void sayHi(){System.out.println("hi,UserController");System.out.println(user);}
}

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

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

相关文章

Excel 国产化替换新方案

前言 在当前数字化转型和信创(信息技术应用创新)战略背景下,企业对于安全性、自主可控性和高效办公工具的需求日益增加。作为一款国产自主研发的高性能表格控件,SpreadJS 正成为替换 Excel 的最佳选择。它不仅全面支持国产化认证…

头部姿态估计代码+教程

前言 头部姿态估计是计算机视觉中的一个具有挑战性的问题,因为它需要完成多个步骤。首先,我们需要在画面中定位人脸,然后识别出各种面部特征点。如今,当人脸正对摄像头时,识别人脸似乎是一个简单的任务。但问题在于&am…

PCIe进阶之TL:First/Last DW Byte Enables Rules Traffic Class Field

1 First/Last DW Byte Enables Rules & Attributes Field 1.1 First/Last DW Byte Enables Rules Byte Enable 包含在 Memory、I/O 和 Configuration Request 中。本文定义了相应的规则。Byte Enable 位于 header 的 byte 7 。对于 TH 字段值为 1 的 Memory Read Request…

计算机网络27、28——Linux命令1、2

1、虚拟机网络前方路径内容 用户名机器名:/$ $表示普通用户,#表示root用户 2、Linux不分盘,都是绝对路径 /表示根目录,表示计算机文件夹下 ~是当前用户的家,表示home文件夹下自己的文件夹 3、bin文件夹下的是可执…

信息收集常用指令

目的 本文主要是记录一些在信息搜集时,常用的提高搜索效率的命令。 后续会继续记录一些用到的更多指令和方法,慢慢更新。 1、inurl “inurl:xxx”是指查找url中包含xxx的网页。 URL:统一资源定位符。统一资源定位系统。可以说包含域名&am…

【数据结构-差分】力扣1589. 所有排列中的最大和

有一个整数数组 nums ,和一个查询数组 requests ,其中 requests[i] [starti, endi] 。第 i 个查询求 nums[starti] nums[starti 1] … nums[endi - 1] nums[endi] 的结果 ,starti 和 endi 数组索引都是 从 0 开始 的。 你可以任意排列…

查看TCP/UDP网络连接通信情况

绪论​ “宿命论是那些缺乏意志力的弱者的借口。 ——罗曼.罗兰” 话不多说安全带系好,发车啦(建议电脑观看)。 主要使用: nestat -nltp n 拒绝显示别名,能显示数字的全部转化成数字l 仅列出有在 Listen (…

动态SQL中的foreach标签【后端 21】

动态SQL中的foreach标签 在Java开发中&#xff0c;特别是在使用MyBatis进行数据库操作时&#xff0c;动态SQL是一项非常强大的功能。MyBatis的<foreach>标签就是动态SQL中最为常用的一个&#xff0c;主要用于处理包含IN子句的查询或者批量插入等操作。本文将详细介绍<…

《程序猿之设计模式实战 · 策略模式》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

论文内容分类与检测系统源码分享

论文内容分类与检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Comput…

掌握顶会流量密码!“Mamba+CNN”双热点组合!轻松找到创新点!

传统视觉模型在处理大规模或高分辨率图像时存在一定限制。然而Mamba与CNN相结合&#xff0c;在处理序列数据和图像数据时有着显著的优势&#xff0c;并且能够有效提升模型计算效率和准确率。 这种结合可以让Mamba在处理长序列数据时既能够捕捉到序列中的时间依赖关系&#xff…

Vue使用qrcodejs2-fix生成网页二维码

安装qrcodejs2-fix npm install qrcodejs2-fix核心代码 在指定父view中生成一个二维码通过id找到父布局 //通过id找到父布局let codeView document.getElementById("qrcode")new QRCode(codeView, {text: "测试",width: 128,height: 128,colorDark: #00…

three.js 热力图

使用three.js 和 heatMap.js 实现在 三维场景中展示热力图的效果&#xff0c;以下代码复制粘贴即可在你的本机运行。 在线编辑运行预览可方位 https://threehub.cn/#/codeMirror?navigationThreeJS&classifyexpand&idheatmap3D 在 https://threehub.cn 中还有很多案例…

力扣 中等 2300.咒语和药水的成功对数

文章目录 题目介绍解法 题目介绍 解法 class Solution {public int[] successfulPairs(int[] spells, int[] potions, long success){Arrays.sort(potions);int n spells.length, m potions.length;int[] pairs new int[n];for (int i 0; i < n; i) {int left 0, righ…

【leetcode】树形结构习题

二叉树的前序遍历 返回结果&#xff1a;[‘1’, ‘2’, ‘4’, ‘5’, ‘3’, ‘6’, ‘7’] 144.二叉树的前序遍历 - 迭代算法 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,…

汉王手写签批控件如何在谷歌、火狐、Edge等浏览器使用

背景 近日&#xff0c;有网友咨询汉王手写签批控件是否可以通过allWebPlugin中间件技术加载到谷歌、火狐、Edge等浏览器&#xff1f;为此&#xff0c;笔者详细了解了一下汉王手写签批控件&#xff0c;它是一个标准的ActiveX控件&#xff0c;曾经主要在IE浏览器使用&#xff0c;…

C语言 | Leetcode C语言题解之第401题二进制手表

题目&#xff1a; 题解&#xff1a; char** readBinaryWatch(int turnedOn, int* returnSize) {char** ans malloc(sizeof(char*) * 12 * 60);*returnSize 0;for (int i 0; i < 1024; i) {int h i >> 6, m i & 63; // 用位运算取出高 4 位和低 6 位if (h &…

Laravel邮件发送:从配置到发邮件的指南!

Laravel邮件发送功能如何实现&#xff1f;怎么使用Laravel发信&#xff1f; Laravel作为一款流行的PHP框架&#xff0c;提供了强大且易用的邮件发送功能。AokSend将详细介绍如何从配置到实际发送邮件的全过程&#xff0c;帮助你快速掌握Laravel邮件发送的技巧。 Laravel邮件发…

对 JavaScript 原型的理解

笔者看了一些有关 JavaScript 原型的文章有感而发&#xff0c;就将所感所悟画了下来如果有理解错误和不足的地方&#xff0c;欢迎各位大佬指出&#xff0c;笔者感激不尽

2024华韵视听大会 “发现佛山”文旅影视产业调研活动-娅米的阳光城堡

9月13日上午&#xff0c;作为“2024华韵视听大会”系列活动之一&#xff0c;“发现佛山”文旅影视产业调研活动在佛山市高明区举行。来自“长风破浪”青年音乐人唱享计划及青年影视人扶持计划&#xff08;下简称“长风破浪”计划&#xff09;的青年唱作人左其铂、陈柏川和青年歌…