导航:首页 > 文件教程 > springimport引入文件

springimport引入文件

发布时间:2025-08-14 19:30:56

『壹』 SpringCloud微服务实现数据权限控制

前章讲了如何进行用户权限验证,它是微服务下统一资源访问权限的控制,就像一道墙保护着SpringCloud集群下的各个业务应用服务。而本章要讲的是权限控制的另一个层面数据权限,意思是控制可访问数据资源的数量。

举个例子:

有一批业务员跟进全国的销售订单。他们被按城市进行划分,一个业务员跟进3个城市的订单,为了保护公司的业务数据不能被所有人都掌握,故每个业务员只能看到自己负责城市的订单数据。所以从系统来讲每个业务员都有访问销售订单的功能,然后再需要配置每个业务员负责的城市,以此对订单数据进行筛选。

要实现此功能有很多方法,如果系统中多个地方都需要类似的需求,那我们就可以将其提出来做成一个通用的功能。这里我介绍一个相对简单的解决方案,以供参考。

一、整体架构

数据权限为作一个注解的形式挂在每一个需要数据权限控制的Controller上,由于和具体的程序逻辑有关故有一定的入侵性,且需要数据库配合使用。

二、实现流程

浏览器传带查询权限范围参数访问Controller,如cities

POSThttp://127.0.0.1:8000/order/queryaccept:*/*Content-Type:application/jsontoken:1e2b2298-8274-4599-a26f-a799167cc82f{"cities":["cq","cd","bj"],"userName":"string"}

通过注解拦截权限范围参数,并根据预授权范围比较,回写在授权范围内的权限范围参数

cities=["cq","cd"]

通过参数传递到DAO层,在SQL语句中拼装出查询条件,实现数据的过滤

select*fromorderwherecityin('cq','cd')三、实现步骤1.注解实现

注解的完整代码,请详见源代码

1)创建注解@Retention(value=RetentionPolicy.RUNTIME)@Target(value={ElementType.METHOD})@Documentedpublic@interfaceScopeAuth{Stringtoken()default"AUTH_TOKEN";Stringscope()default"";String[]scopes()default{};}

此注解为运行时RetentionPolicy.RUNTIME作用在方法上ElementType.METHOD的

token:获取识别唯一用户的标识,与用户数据权限存储有关

scope,scopes:预请求的数据权限范围

2)AOP实现注解publicclassScopeAuthAdvice{@Around("@annotation(scopeAuth)")publicObjectbefore(,ScopeAuthscopeAuth)throwsThrowable{//...省略过程//获取tokenStringauthToken=getToken(args,scopeAuth.token(),methodSignature.getMethod());//回写范围参数setScope(scopeAuth.scope(),methodSignature,args,authToken);returnthisJoinPoint.proceed();}/***设置范围*/privatevoidsetScope(Stringscope,,Object[]args,StringauthToken){//获取请求范围Set<String>requestScope=getRequestScope(args,scope,methodSignature.getMethod());ScopeAuthAdapteradapter=newScopeAuthAdapter(supplier);//已授权范围Set<String>authorizedScope=adapter.identifyPermissionScope(authToken,requestScope);//回写新范围setRequestScope(args,scope,authorizedScope,methodSignature.getMethod());}/***回写请求范围*/privatevoidsetRequestScope(Object[]args,StringscopeName,Collection<String>scopeValues,Methodmethod){//解析SPEL表达式if(scopeName.indexOf(SPEL_FLAG)==0){ParseSPEL.setMethodValue(scopeName,scopeValues,method,args);}}}

此为演示代码省略了过程,主要功能为通过token拿到预先授权的数据范围,再与本次请求的范围做交集,最后回写回原参数。

过程中用到了较多的SPEL表达式,用于计算表达式结果,具体请参考ParseSPEL文件

3)权限范围交集计算publicclassScopeAuthAdapter{;publicScopeAuthAdapter(AuthQuerySuppliersupplier){this.supplier=supplier;}/***验证权限范围*@paramtoken*@paramrequestScope*@return*/publicSet<String>identifyPermissionScope(Stringtoken,Set<String>requestScope){Set<String>authorizeScope=supplier.queryScope(token);StringALL_SCOPE="AUTH_ALL";StringUSER_ALL="USER_ALL";if(authorizeScope==null){returnnull;}if(authorizeScope.contains(ALL_SCOPE)){//如果是全开放则返回请求范围returnrequestScope;}if(requestScope==null){returnnull;}if(requestScope.contains(USER_ALL)){//所有授权的范围returnauthorizeScope;}//移除不同的元素requestScope.retainAll(authorizeScope);returnrequestScope;}}

此处为了方便设置,有两个关键字范围

AUTH_ALL:预设所有范围,全开放的意思,为数据库预先设置值,请求传什么值都通过

USER_ALL:请求所有授权的范围,请求时传此值则会以数据库预设值为准

4)spring.factories自动导入类配置org.springframework.boot.autoconfigure.=fun.barryhome.cloud.annotation.ScopeAuthAdvice

如果注解功能是单独项目存在,在使用时有可能会存在找不到引入文件的问题,可通过此配置文件自动载入需要初始化的类

2.注解使用@ScopeAuth(scopes={"#orderDTO.cities"},token="#request.getHeader("X-User-Name")")@PostMapping(value="/query")publicStringquery(@RequestBodyOrderDTOorderDTO,HttpServletRequestrequest){returnArrays.toString(orderDTO.getCities());}

在需要使用数据权限的controller方法上增加@ScopeAuth注解

scopes={"#orderDTO.cities"}:表示取输入参数orderDTO的cities值,这里是表达式必须加**#**

实际开发过程中,需要将**orderDTO.getCities()**带入后续逻辑中,在DAO层将此拼装在SQL中,以实现数据过滤功能

3.实现AuthStoreSupplier

AuthStoreSupplier接口为数据权限的存储接口,与AuthQuerySupplier配合使用,可按实际情况实现

此接口为非必要接口,可由数据库或Redis存储(推荐),一般在登录的同时保存在Redis中

4.实现AuthQuerySupplier

AuthQuerySupplier接口为数据权限查询接口,可按存储方法进行查询,推荐使用Redis

@{@AutowiredprivateRedisTemplate<String,String>redisTemplate;/***查询范围*/@OverridepublicSet<String>queryScope(Stringkey){StringAUTH_USER_KEY="auth:logic:user:%s";StringredisKey=String.format(AUTH_USER_KEY,key);List<String>range=redisTemplate.opsForList().range(redisKey,0,-1);if(range!=null){returnnewHashSet<>(range);}else{returnnull;}}}

在分布式结构里,也可将此实现提出到权限模块,采用远程调用方式,进一步解耦

5.开启数据权限@EnableScopeAuth@EnableDiscoveryClient@{publicstaticvoidmain(String[]args){SpringApplication.run(OrderApplication.class,args);}}四、综述

至此数据权限功能就实现了。在微服务器架构中为了实现功能的复用,将注解的创建和AuthQuerySupplier的实现提取到公共模块中,那么在具体的使用模块就简单得多了。只需增加@ScopeAuth注解,配置好查询方法就可以使用。

五、源代码

文中代码由于篇幅原因有一定省略并不是完整逻辑,如有兴趣请Fork源代码gitee.com/hypier/barry-cloud/tree/master/cloud-auth-logic

『贰』 springboot启动配置(springboot启动配置文件加载顺序)

SpringBoot的启动过程及部分注解

相比于以前繁琐的基于Spring的Web应用,SpringBoot通过默认配置很多框架的方式,极大的简化了项目的搭建以及开发流程。

一个简单的SpringBoot应用只需要三步:

1.在pom.xml中引入所需要的依赖

2.在application.yml配置所需的数据源

3.在启动类中加入@SpringBootApplication注解以及run方法

启动流程

1.SpringApplication.run()启动

2.新建SpringApplication实例,主要是初始化一些成员变量,参数列表等

prepareContext():

refreshContext()中refresh():

核心注解(部分)

@SpringBootAppliction启动类

@Configuration+@EnableAutoConfiguration+@ComponentScan

@Configuration

允许在应用上下文中注册其它的bean,可用@Component代替

@Configuration会为bean创建一个代理类,这个类会拦截所有被@Bean修饰的方法,从容器中返回所需要的单例对象;@Component不会创建代理类,会直接执行方法,每次返回一个新的对象

@EnableAutoConfiguration

启用springboot自动装配,该参数位于spring.factories中org.springframework.boot.autoconfigure.EnableAutoConfiguration

@ComponentScan

扫描被@Component(@Service,@Controller)注解的bean,注解默认会扫描该类所在的包下所有的类

@Autowired

自动导入对象到类中,被注入进的类被Spring容器管理Service-Controller

@Component

通用的注解,可标注任意类为Spring组件

@Repository持久层

@Service服务层

@Controller控制层

@Bean

用于告诉方法产生一个Bean对象,然后这个对象交给IOC容器管理。产生这个Bean对象的方法Spring只会调用一次,然后将这个Bean对象放在IOC容器中

二、springboot配置文件

1.配置文件

SpringBoot使用一个全局的配置文件

application.properties

application.yml

配置文件的作用:修改SpringBoot自动配置的默认值,SpringBoot在底层都给我们自动

配置好。有什么配置项,可以移步官方文档

配置文件一般放在src/main/resources目录或者类路径/confifig下,当然还有很多位置可

以放,它们会有不同优先级,后面会讲到。

YAML(YAMLAin'tMarkupLanguage)

简单介绍

!--绑定配置文件处理器,配置文件进行绑定的时候就会有提示--

dependency

groupIdorg.springframework.boot/groupId

artifactIdspring-boot-configuration-processor/artifactId

optionaltrue/optional

/dependency

!--将应用打包成一个可执行Jar包,直接使用java-jarxxxx的命令来执行--

build

plugins

plugin

groupIdorg.springframework.boot/groupId

artifactIdspring-boot-maven-plugin/artifactId

/plugin

/plugins

/build以前的配置文件:大多是xml

.yml是YAML语言的文件,以数据为中心,比json、xml等更适合做配置文件

全局配置文件的可以对一些默认配置值进行修改

配置实例

xml:

yml:

2.YAML语法

基本语法

K:(空格)V标识一对键值对

以空格的缩进来控制层级关系

只要是左对齐的一列数据,都是同一层级的

属性和值也是大小写敏感

实例:

值的写法

普通的值

k:v字面量直接来写,字符串默认不用添加单引号

""双引号不会转义字符串里面的特殊字符;

server

port8081/port

/server

server:

port:8081

server:

port:8081

path:/hello//冒号后面的空格不要拉下''单引号会转义字符,特殊字符最终是一个普通的字符串

对象

普通写法:

行内写法

frends:{lastName:zhang,age:18}

Map

示例:

maps:{k1:v1,k2:v2}

数组

普通写法:

pets://varonj={pets:['cat','pig','dog']}

-cat

-pig

-dog

行内写法

pets:[cat,pig,dog]

配置文件获取

将配置文件中的每一个值映射到此组件中

1.Persion

name:"wang qian"//输出:wang换行qian

frends:

lastName:zhang

age:20packagecom.wrq.boot.bean;

@Component

@ConfigurationProperties(prefix="persion")

publicclassPersion{

privateStringname;

privateintage;

privatedoubleweight;

privatebooleanboss;

privateDatebirth;

privateMapString,Objectmaps;

privateListObjectlist;

privateDogdog;

此处,这个bean的getter、setter和tostring方法已经省略,千万不能忽略!

}

@ConfifigurationProperties意思是:我们类里面的属性和配置文件中的属性做绑定

不使用此注解,可以在bean的属性添加@value()注解,如下:

@Component

//@ConfigurationProperties(prefix="persion")

publicclassPersion{

@value("${persion.name}")//$()读取配置文件、环境变量中的值

privateStringname;

@value("#{11*2}")//#{SpEL}采用表达式

privateintage;

@value("true")//直接赋值

privatebooleanboos;

}

此处采用@ConfifigurationProperties的方式,@value()和@ConfifigurationProperties的

区别见下方表格。prefifix="persion"配置文件中那个下面的属性来一一映射

@Component如果想要这个注解起作用,必须放到容器里面

2.Dog

packagecom.wrq.boot.bean;

publicclassDog{//用作Persion中的属性

privateStringname;

privateintage;

此处,这个bean的getter、setter和tostring方法已经省略,千万不能忽略!

}

3.配置文件

方式一:application.yml

persion:

name:王大锤

age:18

weight:125

boss:false

birth:2018/5/5

maps:{k1:v1,k2:v2}

list:

-wangli

-wang

dog:

name:xiaogou

age:2

方式二:application.propertiespersion.name=王大锤

persion.age=18

persion.weight=125

persion.boss=false

persion.birth=2018/5/5

persion.maps.k1=v1

persion.maps.k2=v2

persion.dog.name=xiaogou

persion.dog.age=15

4.测试类:BootApplicationTests

packagecom.wrq.boot;

@RunWith(SpringRunner.class)

@SpringBootTest

{

@Autowired

Persionpersion;

@Test

publicvoidcontextLoads(){

System.out.print(persion);

}

}

5.运行BootApplicationTests方法

控制台打印:

application.yml的结果:

Persion{name='王大锤',age=18,weight=125.0,boss=false,birth=SatMay

0500:00:00CST2018,maps={k1=v1,k2=v2},list=[wangli,wang],

dog=Dog{name='xiaogou',age=2}}

application.properties的结果:

Persion{name='????????',age=18,weight=125.0,boss=false,birth=Sat

May0500:00:00CST2018,maps={k2=v2,k1=v1},list=[wangli,wang],

dog=Dog{name='xiaogou',age=15}}

把Bean中的属性和配置文件绑定,通过yml文件和properties都可以做到,但是properties

文件出现乱码。

properties中文读取乱码:File-Settings-FileEncodings最底部选utf-8、Tranparent打

上勾

注解比较

@value和@ConfifigurationProperties获取值比较

名词解释:

松散绑定

last-name和lastName都可以获取导致,则代表支持松散绑定

JSR303@Component

@ConfigurationProperties(prefix="persion")//如果使用的是@value注入值

时,无法使用校验

@Validated//添加此注解

publicclassPersion{

@Email//配置文件书写的属性必须是邮箱格式,不符合报错!

privateStringname;

}

复杂类型封装

如果获取配置文件中map的值时,@value是获取不到值的

@value("${persion.maps}")//由于使用的是@value,无法获取配置文件中的map

privateMapString,Objectmaps;

@PropertySource

@PropertySource:加载指定配置文件

@ConfifigurationProperties()默认是从全局配置文件中获取值,也就是

application.properties这个文件中获取值。

如果做的配置很多,全局的配置文件就会特别大,为了方便管理。我会创建不同的配置文

件定向管理不同的配置。

如创建persion.properties文件单独存放persion需要的配置

@PropertySource就是用来导入创建的配置文件

示例:

1.persion.properties

同时把两个全局的配置中关于Persion的配置都注释掉persion.name=王弟弟

persion.age=18

persion.weight=125

persion.boss=false

persion.birth=2018/5/5

persion.maps.k1=v1

persion.maps.k2=v2

persion.dog.name=xiaogou

persion.dog.age=15

2.Persion

packagecom.wrq.boot.bean;

@Component

@PropertySource(value={"classpath:persion.properties"})

@ConfigurationProperties(prefix="persion")

publicclassPersion{

privateStringname;

privateintage;

privatedoubleweight;

privatebooleanboss;

privateDatebirth;

privateMapString,Objectmaps;

privateListObjectlist;

privateDogdog;

此处,这个bean的getter、setter和tostring方法已经省略,千万不能忽略!

}

这样运行测试类,控制台就可以打印persion.properties中的数据。

通过下面的注解,把类路径下的persion.properties加载进来。并且把persion开头的数

据进行绑定。

@PropertySource(value={"classpath:persion.properties"})@ConfifigurationProperties(prefifix="persion")

@ImportResource

@ImportResource:导入Spring的配置文件,让配置文件生效。

示例:

1.com.wrq.boot.service

packagecom.wrq.boot.service;

/**

*Createdbywangqianon2019/1/12.

*/

publicclassHelloService{

}

2.resources目录手动建立bean.xml

?xmlversion="1.0"encoding="UTF-8"?

beansxmlns=""

xmlns:xsi=""

xsi:schemaLocation="

"

beanid="helloService"class="com.wrq.boot.service.HelloService"

/bean

/beans

3.测试类

packagecom.wrq.boot;

@RunWith(SpringRunner.class)

@SpringBootTest

{

@Autowired

ApplicationContextioc;@Test

publicvoidtestConfig(){

booleanb=ioc.containsBean("helloService");

System.out.print(b);

}

}

试图通过添加一个Spring的配置文件bean.xml来把HelloService注入进去。

运行测试类结果:false

结果表明IoC容器中并不包含HelloService,即:配置文件bean.xml没有生效

解决方式

方式一:主程序中进行配置@ImportResouece注解

packagecom.wrq.boot;

@ImportResource(locations={"classpath:bean.xml"})//通过此配置是

bean.xml生效

@SpringBootApplication

publicclassBootApplication{

publicstaticvoidmain(String[]args){

//应用启动起来

SpringApplication.run(BootApplication.class,args);

}

}

方法二:通过配置类实现,这种方式也是SpringBoot推荐的

1.com.wrq.boot.confifigpackagecom.wrq.boot.config;

/**

*Createdbywangqianon2019/1/12.

*/

@Configuration

publicclassMyConfig{

//将方法的返回值添加到容器之中,并且容器中这个组件的id就是方法名

@Bean

(){

System.out.print("通过@Bean给容器添加组件了..");

returnnewHelloService();

}

}

@Confifiguration标注这是一个配置类

通过@Bean注解,将方法的返回值添加到容器之中,并且容器中这个组件的id就是方

法名

2.把主程序类中@ImportResource()配置注释掉

3.测试成功,添加了HelloService()组件

3.配置文件占位符

随机数

RandomValuePropertySource:配置文件中可以使用随机数

${random.value}

${random.int}

${random.long}

${random.uuid}

${random.int(10)}

${random.int[1024,65536]}

属性配置占位符可以在配置文件中引用前面配置过的属性(优先级前面配置过的这里都能用)

${app.name:默认值}来指定找不到属性时的默认值

persion.name=王弟弟${random.uuid}

persion.age=${random.int}

persion.dog.name=${persion.name}_dog

4.Profifile多环境支持

Profifile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式

快速切换环境

1.多Profifile的方式

格式:application-{profifile}.properties/yml

application-dev.properties

application-prod.properties

默认采用application.properties配置文件,如果使用别的,需要激活:

1.application.properties中配置:

#激活application-dev.properties配置文件

spring.profiles.active=dev

2.application-dev.properties:

server.port=8082

3.运行BootApplication主程序:

2019-01-1220:46:09.345INFO14404---[main]

s.b.c.e.t.:Tomcatstartedonport(s):

8082(http)

2.多文档块的方式

除了上方多Profifile的方式来切换环境,也可以通过YAML多文档块的方式。示例:

ap

阅读全文

与springimport引入文件相关的资料

热点内容
我国超过10万的大数据有哪些 浏览:307
有哪些百科网站 浏览:728
cad转出文件损坏 浏览:264
新人开播后台数据怎么才能及格 浏览:144
电脑店u盘取消赞助密码 浏览:714
什么叫做面向对象编程 浏览:992
压缩文件素材怎么使用 浏览:387
plc与上位机如何编程 浏览:140
苹果7怎么设置护眼模式 浏览:860
在线检测网络 浏览:903
华美网络采集器 浏览:874
win加密文件找不到了 浏览:938
jsp页面引入ocx控件 浏览:466
东莞哪里有模架编程培训学校 浏览:515
编程时如何引入图片与音乐 浏览:72
用usb串口下载程序的问题 浏览:153
只用g71粗循环怎么编程 浏览:87
springimport引入文件 浏览:908
excel另存为后文件变大 浏览:615
排序如何和比较大小一起编程 浏览:848

友情链接