当前位置:首页 » 文件传输 » spring接口不用实现就能访问
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

spring接口不用实现就能访问

发布时间: 2022-11-21 00:35:43

1. spring boot框架中怎样访问jpa接口中的方法

blic interface UserRepository extends JpaRepository<User, Long> {

User findByName(String name);

@Query("from User u where u.name=:name")
User findUser(@Param("name") String name);

}

我们只需要通过编写一个继承自 JpaRepository 的接口就能完成数据访问,下面以一个具体实例来体验Spring-data-jpa给我们带来的强大功能。
使用示例
由于Spring-data-jpa依赖于Hibernate。如果您对Hibernate有一定了解,下

2. Spring Security 接口认证鉴权入门实践指南

Web API 接口服务场景里,用户的认证和鉴权是很常见的需求,Spring Security 据说是这个领域里事实上的标准,实践下来整体设计上确实有不少可圈可点之处,也在一定程度上印证了小伙们经常提到的 “太复杂了” 的说法也是很有道理的。

本文以一个简单的 SpringBoot Web 以应用为例,重点介绍以下内容:

创建 SpringBoot 示例,用于演示 Spring Security 在 SpringBoot 环境下的应用,简要介绍四部分内容:pom.xml、application.yml、IndexController 和 HelloController。

boot-example 是用于演示的 SpringBoot 项目子模块(Mole)。

SpringBoot 应用名称为 example,实例端口为 9999

IndexController 实现一个接口:/。

HelloController 实现两个接口:/hello/world 和 /hello/name。

编译启动 SpringBoot 应用,通过浏览器请求接口,请求路径和响应结果:

SpringBoot 示例准备完成。

SpringBoot 集成 Spring Security 仅需要在 pom.xml 中添加相应的依赖: spring-boot-starter-security ,如下:

编译启动应用,相对于普通的 SpringBoot 应用,我们可以在命令行终端看到 特别 的两行日志:

表示 Spring Security 已在 SpringBoot 应用中生效。 默认 情况下,Spring Security 自动化 地帮助我们完成以下三件事件:

使用 Spring Security 默认为我们生成的用户名和密码进行登录(Sign in),成功之后会自动重定向至 / :

之后我们就可以通过浏览器正常请求 /hello/world 和 /hello/name。

默认情况下,Spring Security 仅支持基于 FormLogin 方式的认证,只能使用固定的用户名和随机生成的密码,且不支持鉴权。如果想要使用更丰富的安全特性:

本文以 Java Configuration 的方式为例进行介绍,需要我们提供一个继承自 WebSecurityConfigurerAdapter 配置类,然后通过重写若干方法进而实现自定义配置。

SecurityConfig 使用 @Configuration 注解(配置类),继承自 WebSecurityConfigurerAdapter ,本文通过重写 configure 方法实现自定义配置。

需要注意: WebSecurityConfigurerAdapter 中有多个名称为 configure 重载方法,这里使用的是参数类型为 HttpSecurity 的方法。

注:Spring Security 默认自动化配置参考 Spring Boot Auto Configuration 。

用以指定哪些请求需要什么样的认证或授权,这里使用 anyRequest() authenticated() 表示所有的请求均需要认证。

表示我们使用 HttpBasic 认证。

编译启动应用,会发现终端仍会输出密码:

因为,我们仅仅改变的是认证方式。

为方便演示,我们使用 CURL 直接请求接口:

会提示我们 Unauthorized ,即:没有认证。

我们按照 HttpBasic 要求添加请求头部参数 Authorization ,它的值:

即:

再次请求接口:

认证成功,接口正常响应。

使用默认用户名和随机密码的方式不够灵活,大部分场景都需要我们支持多个用户,且分别为他们设置相应的密码,这就涉及到两个问题:

对于 读取 ,Spring Security 设计了 UserDetailsService 接口:

实现按照用户名(username)从某个存储介质中加载相对应的用户信息(UserDetails)。

用户名,客户端发送请求时写入的用于用户名。

用户信息,包括用户名、密码、权限等相关信息。

注意:用户信息不只用户名和用户密码。

对于 存储 ,Spring Security 设计了 UserDetailsManager 接口:

创建用户信息

修改用户信息

删除用户信息

修改当前用户的密码

检查用户是否存在

注意: UserDetailsManager 继承自 UserDetailsService

也就是说,我们可以通过提供一个已实现接口 UserDetailsManager * 的类,并重写其中的若干方法,基于某种存储介质,定义用户名、密码等信息的存储和读取逻辑;然后将这个类的实例以 Bean 的形式注入 Spring Security,就可以实现用户名和密码的自定义。

实际上,Spring Security 仅关心如何 读取 存储 可以由业务系统自行实现;相当于,只实现接口 UserDetailsService 即可。

Spring Security 已经为我们预置了两种常见的存储介质实现:

InMemoryUserDetailsManager和 JdbcUserDetailsManager 均实现接口 UserDetailsManager ,本质就是对于 UserDetails CRUD 。我们先介绍 UserDetails ,然后再分别介绍基于内存和数据库的实现。

UserDetails是用户信息的抽象接口:

获取用户名。

获取密码。

获取权限,可以简单理解为角色名称(字符串),用于实现接口基于角色的授权访问,详情见后文。

获取用户是否可用,或用户/密码是否过期或锁定。

Spring Security 提供了一个 UserDetails 的实现类 User ,用于用户信息的实例表示。另外, User 提供 Builder 模式的对象构建方式。

设置用户名称。

设置密码,Spring Security 不建议使用明文字符串存储密码,密码格式:

其中,id 为加密算法标识,encodedPassword 为密码加密后的字符串。这里以加密算法 bcrypt 为例,详细内容可参考 Password Storage 。

设置角色,支持多个。

UserDetails实例创建完成之后,就可以使用 UserDetailsManager 的具体实现进行存储和读取。

InMemoryUserDetailsManager是 Spring Security 为我们提供的基于内存实现的 UserDetailsManager

使用 @Bean InMemoryUserDetailsManager 实例注入 Spring Security。

创建 InMemoryUserDetailsManager 实例之后,并不是必须立即调用 createUser 添加用户信息,也可以在业务系统的其它地方获取已注入的 InMemoryUserDetailsManager 动态存储 UserDetails 实例。

编译启动应用,使用我们自己创建的用户名和密码(userA/123456)访问接口:

基于内存介质自定义的用户名和密码已生效,接口正常响应。

JdbcUserDetailsManager是 Spring Security 为我们提供的基于数据库实现的 UserDetailsManager ,相较于 InMemoryUserDetailsManager 使用略复杂,需要我们创建数据表,并准备好数据库连接需要的数据源(DataSource), JdbcUserDetailsManager 实例的创建依赖于数据源。

JdbcUserDetailsManager可以与业务系统共用一个数据库数据源实例,本文不讨论数据源的相关配置。

Mysql 为例,创建数据表语句:

其他数据库语句可参考 User Schema 。

JdbcUserDetailsManager实例的创建与注入,除

之外,整体流程与 InMemoryUserDetailsManager 类似,不再赘述。

在业务系统中获取已注入的 JdbcUserDetailsManager 实例,可以动态存储 UserDetails 实例。

编译启动应用,使用我们自己创建的用户名和密码(userA/123456)访问接口:

基于数据库介质自定义的用户名和密码已生效,接口正常响应。

Spring Security 可以提供基于角色的权限控制:

假设,存在两个角色 USER(普通用户) 和 ADMIN(管理员),

角色 USER 可以访问接口 /hello/name,

角色 ADMIN 可以访问接口 /hello/world,

所有用户认证后可以访问接口 /。

我们需要按上述需求重新设置 HttpSecurity

设置角色 USER 可以访问接口 /hello/name。

设置角色 ADMIN 可以访问接口 /hello/world。

设置其他接口认证后即可访问。

mvcMatchers 支持使用通配符。

创建属于角色 USER 和 ADMIN 的用户:

用户名:userA,密码:123456,角色:USER

用户名:userB,密码:abcdef,角色:ADMIN

对于用户 userA

使用用户 userA 的用户名和密码访问接口 /:

认证通过,可正常访问。

使用用户 userA 的用户名和密码访问接口 /hello/name:

认证通过,鉴权通过,可正常访问。

使用用户 userA 的用户名和密码访问接口 /hello/world:

认证通过,用户 userA 不属于角色 ADMIN,禁止访问。

使用用户 userA 的用户名和密码访问接口 /:

认证通过,可正常访问。

对于用户 userB

使用用户 userB 的用户名和密码访问接口 /:

认证通过,可正常访问。

使用用户 userB 的用户名和密码访问接口 /hello/world:

认证通过,鉴权通过,可正常访问。

使用用户 userB 的用户名和密码访问接口 /hello/name:

认证通过,用户 userB 不属于角色 USER,禁止访问。

这里可能会有一点奇怪,一般情况下我们会认为 管理员 应该拥有 普通用户 的全部权限,即普通用户 可以访问接口 /hello/name,那么 管理员 应该也是可以访问接口 /hello/name 的。如何实现呢?

方式一,设置用户 userB 同时拥有角色 USER 和 ADMIN;

这种方式有点不够“优雅”。

方式二,设置角色 ADMIN 包含 USER;

Spring Security 有一个 Hierarchical Roles 的特性,可以支持角色之间的 包含 操作。

使用这个特性要特别注意两个地方:

前文使用的是 HttpSecurity.authorizeHttpRequests 方法,此处需要变更为 HttpSecurity.authorizeRequests 方法。

使用 RoleHierarchy 以 Bean 的方式定义角色之间的 层级关系 ;其中,“ROLE_” 是 Spring Security 要求的固定前缀。

编译启动应用,使用用户 userB 的用户名和密码访问接口 /hello/name:

认证通过,鉴权通过,可正常访问。

如果开启 Spring Security 的 debug 日志级别,访问接口时可以看到如下的日志输出:

可以看出,Spring Security 可以从角色 ADMIN 推导出用户实际拥有 USER 和 ADMIN 两个角色。

Hierarchical Roles 文档中的示例有明显错误:

接口 RoleHierarchy 中并不存在方法 setHierarchy 。前文所述 authorizeRequests RoleHierarchy 结合使用的方法是结合网络搜索和自身实践得出的,仅供参考。

另外, authorizeHttpRequests RoleHierarchy 结合是没有效果的, authorizeRequests authorizeHttpRequests 两者之间的区别可以分别参考 Authorize HttpServletRequests with AuthorizationFilter 和 Authorize HttpServletRequest with FilterSecurityInterceptor 。

鉴权的前提需要认证通过;认证不通过的状态码为401,鉴权不通过的状态码为403,两者是不同的。

Spring Security 异常主要分为两种:认证失败异常和鉴权失败异常,发生异常时会分别使用相应的默认异常处理器进行处理,即:认证失败异常处理器和鉴权失败异常处理器。

使用的认证或鉴权实现机制不同,可能使用的默认异常处理器也不相同。

Spring Security 认证失败异常处理器:

如前文所述,认证失败时,Spring Security 使用默认的认证失败处理器实现返回:

如果想要自定义返回内容,则可以通过自定义认证失败处理器实现:

authenticationEntryPoint()会创建返回一个自定义的 AuthenticationEntryPoint 实例;其中,使用 HttpServletResponse.getWriter().print() 写入我们想要返回的内容:401。

httpBasic().authenticationEntryPoint(authenticationEntryPoint())使用我们自定义的 AuthenticationEntryPoint 替换 HttpBasic 默认的 BasicAuthenticationEntryPoint

编译启动应用,使用不正确的用户名和密码访问接口 /:

认证不通过,使用我们自定义的内容 401 返回。

Spring Security 鉴权失败异常处理器:

如前文所述,认证失败时,Spring Security 使用默认的认证失败处理器实现返回:

如果想要自定义返回内容,则可以通过自定义鉴权失败处理器实现:

自定义鉴权失败处理器与认证失败处理器过程类似,不再赘述。

编译启动应用,使用用户 userA 的用户名和密码访问接口 /hello/world:

鉴权不通过,使用我们自定义的内容 403 返回。

exceptionHandling()也是有一个 authenticationEntryPoint() 方法的;对于 HttpBasic 而言,使用 exceptionHandling().authenticationEntryPoint() 设置自定义认证失败处理器是不生效的,具体原因需要大家自行研究。

前文介绍两种认证方式: FormLogin HttpBasic ,Spring Security 还提供其他若干种认证方式,详情可参考 Authentication Mechanisms 。

如果我们想实现自己的认证方式,也是比较简单的。Spring Security 本质就是 过滤器 ,我们可以实现自己的认证过滤器,然后加入到 Spring Security 中即可。

认证过滤器核心实现流程:

除去抛出异常的情况外, filterChain.doFilter(servletRequest, servletResponse); 是必须保证被执行的。

理解认证过滤器涉及的概念会比较多,详情参考 Servlet Authentication Architecture 。

认证过滤器创建完成之后,就可以加入到 Spring Security 中:

Spring Security 根据我们配置的不同,会为我们自动按照一定的次序组装一条 过滤器链 ,通过这条链上的若干过滤器完成认证鉴权的。我们需要把自定义的认证过滤器加到这个链的 合适位置 ,这是选取的位置是在 ExceptionTranslationFilter 的前面。

过滤器链的顺序可以参考 Security Filters 。

ExceptionTranslationFilter 的作用可以参考 Handling Security Exceptions 。

使用自定义认证过滤器时,自定义认证失败异常处理器和鉴权失败异常处理器的设置方法。

编译启动应用,我们会发现可以在不填入任何认证信息的情况下直接访问接口 / 和 /hello/name,因为模拟用户已认证且角色为 USER;访问接口 /hello/world 时会出现提示 403。

Spring Security 自身包含的内容很多,官方文档也不能很好的讲述清楚每个功能特性的使用方法,很多时候需要我们自己根据文档、示例、源码以及他人的分享,尽可能多的实践,逐步加深理解。

3. Spring的通知有哪几种类型

Term 术语 Definition 定义 Concern A particular issue (关注特定问题) 感兴趣应用的特定问题、概念、范围。例如,事务管理、持久化、日志、安全等。 Crosscutting Concern (横切关注点) 在关注点实现中贯穿了很多类,这在面向对象(OOP)中通常很难实现和维护。 Aspect(切面) 模块化的横切关注点,通过代码的聚合和隔离实现。 Join Point(连接点) 在程序或者类执行时的一个点。在Spring的AOP实现中,连接点总是一个方法调用。其他的例子包括访问字段(包括实例中字段的读写),变量和异常处理。 Advice(通知) 特定连接点所采取的动作。Spring有几种不同类型的通知,包括around、before、throws和after returning。在这几种类型的通知中,around是最强大的,在方法调用的前后都有执行一些操作的机会。之前用到的TraceInterceptor就是around类型的通知,它实现了AOP联盟的MethodInterceptor接口。通过实现下面的Spring接口可以使用其他类型的通知: �0�1MethodBeforeAdvice �0�1ThrowsAdvice �0�1AfterReturningAdvicePointcut(切入点) 连接点的集合,这些连接点确认何时一个通知将会触发。切入点通常使用正则表达式或者是通配符语法。 Introction (引入) 添加字段或者方法到一个通知类。Spring允许你在任何通知对象上引入新的接口。例如,你可以使用引入以便让任意对象实现IsModified接口,来简化缓存。 Weaving(组织) 装配切面来创建一个被通知对象。可以在编译期间完成(像AspectJ做的那样)也可以在运行时完成。本章后面的组织策略部分详细讨论不同的组织策略(也就是实现AOP)。 Interceptor (拦截器) 一种AOP实现策略,对与特点的连接点,可能存在一个拦截器链。 AOP Proxy(AOP代理) AOP框架创建的对象,包括通知。在Spring中,一个AOP代理可能是JDK动态代理或者是CGLIB代理。 Target Object (目标对象) 包含连接点的对象。在使用拦截的框架中,它是在拦截器链末端的对象实例。也叫做被通知对象或者被代理对象。 切面。 用个比喻会更形象一些。可以把切面理解成一把菜刀,而其他方法就好像是黏糕,如果你要把所有的黏糕都在某个 位置切断,那么就用这个菜刀就行了。这个菜刀,就是我们需要的切面类。 例如execution(* com.xyz.someapp.service.*.*(..)) 尾部(After),还是首尾(Around)等等。 这些“插入”的代码都是程序运行的时候动态插入的,所以看起来很神奇

4. java程序是不是应用了接口,就基本上可以实现spring了

当然不是了,spring是Java EE里最成功的一个框架,要实现spring需要把spring的jar包以及其他相关的jar包加到项目路径里,而且还要有很多配置。知识spring里用的接口多一点,并不是用了接口就实现了spring,接口是java se里的一个基本特性

5. Spring核心接口是

1.BeanFactory最基础最核心的接口
重要的实现类有:
XmlBeanFactory,以及ApplicationContext接口下的类

2.Resource接口,可以通用地访问文件资源
1)ClassPathResource:读取得形式为"classpath:ApplicationContext.xml"
2)FileStstemResource:读取得形式为"file:c:\spring\src\ApplicationContext.xml"
3)ServletContextResource:读取得形式为"WEB-INF\ApplicationContext.xml"
//ResourceLoader类用于载入Resource

3.FactoryBean工厂bean
它本身在bean factory中定义,同时又是用于创建目标bean的工厂
spring有以下实现:
1)JndiObjectFactoryBean:通过JNDI查找获取对象
2)LocalSessionFactoryBean:用于在本地装配Hibernate SessionFactory
3)LocalSessionFactoryBean:用于在本地装配JDO PersistenceManagerFactory
4)ProxyFactoryBean:用于获取AOP的代理
5)TransactionProxyFactoryBean:用于为对象创建事务代理,用于实现简捷易用的声明性事务代理
6)RmiProxyFactoryBean:为通过RMI访问的远程对象创建一个代理

4.ApplicationContext加强了BeanFactory的功能,支持以下功能
1)国际化支持
2)资源访问
3)事件监听机制
它的重要的实现类有:
,ClassPathXmlApplication,XmlWebApplicationContext

5.Bean生命周期的回调接口
BeanFactoryPostProcessor,InitializingBean,DisposableBean,BeanFactoryAware,ApplicationContextAware,ResourceLoader,BeanPostProcessor

6.MessageSource接口
它的实现类有ResourceBundleMessageSource,.后者在属性文件修改后会重新载入

如果喜欢共同谈论, 加msn :[email protected]

6. 为什么ibatis在和spring一起使用的时候,可以不用实现类就用接口就可以查出来

因为sql语句都是写在ibatis的配置文件中了,<select id="方法名" 这个是ibatis的配置中sql查询语言的节点,如果你要写查询语句,就配置这个节点,把sql语句写在这个节点里面,id属性不是方法名,是这个节点对应的一个id值,ibatis在调用查询方法的时候,在实现中中需要把这个id值作为参数告诉ibatis,从而ibatis知道去调用那条语句,

7. spring 为什么要先写接口,再写实现类

首先你要理解OOP的思想,是面向接口编程.
什么叫面向接口编程呢?
假如你买了一个多媒体设备,它给了你一个遥控,你想要知道的只是按什么按钮,它会播放什么
而遥控里面是怎样运行,还有屏幕里面怎么工作,你想知道吗?
你完全不会去想了解.
那如果多媒体设备需要更新,比如优化内部运行效率,
但是优化完了,遥控的按钮不变,设备的所有操作方式都不变,按这个按钮还是显示相同的东西
那内部怎么变化你完全不需要在意.

这就是面向接口编程.
无论类的内部怎么实现,它对外的接口不变,那它的使用方式就不会变
假设Main类要使用D类的一个draw的方法,
方法名叫 draw():void
不管draw里面是怎样的,Main类里就是这样用,
那么你就从这个接口出发,里面怎么实现是D类的事了,Main类只关心怎么用而已.
其他类要使用它,还是相同
这就大大减少了维护的成本.
因为如果D类出问题,Main类是完全不用改变的.

从上观察,公开的接口越多,维护成本就越大.
维护就越麻烦.所以我们先写接口,定死了公开的接口,
那维护就很方便,出错也只是一个类的事,而不用同时修改多个协同类

8. spring,applicationContext.xml配置,加载一直报错啊,类用了接口,不用接口同样配置就可以。求救啊

最好把applicationContext.xml关键代码贴出来。从错误信息来看,应该是tService这个属性没找到,看下tService对应的bean有没有在xml中作配置。

9. 为什么spring注入接口正确而注入接口的实现

原因所在:出现如果直接注入实现类会出现没有对应的bean,因为我们通过实现类来继承的接口,然而,必须使用jdk提供的动态代理放法,而不使用接口直接对实现类进行注入,则为cglib的注入,而不能既继承接口又使用实现类来注入的方式,这样两种代理类都是没有办法使用的。
解决方案:1.直接通过jdk去生成动态代理类,(原理要求必须实现接口)
2.通过cglib去实现接口,直接使用代理类,而不能实现接口。

10. 怎么把spring boot 在没有验证的情况下也访问接口

呵呵,联想的有些电脑,其实很多笔记本都是那样的,它的开机启动也就是boot是按F12的,有些是按ESC,有些是F2,联想的大多是F12