是不是该先看servlet篇,再看触发器是不是组合逻辑电路篇

随笔 - 2315&
文章 - 0&评论 - 0&trackbacks - 0
本文实例讲述了Oracle触发器用法。分享给大家供大家参考,具体如下:
一、触发器简介
触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行。
因此触发器不需要人为的去调用,也不能调用。
然后,触发器的触发条件其实在你定义的时候就已经设定好了。
这里面需要说明一下,触发器可以分为语句级触发器和行级触发器。
详细的介绍可以参考网上的资料,简单的说就是语句级的触发器可以在某些语句执行前或执行后被触发。而行级触发器则是在定义的了触发的表中的行数据改变时就会被触发一次。
具体举例:
1、 在一个表中定义的语句级的触发器,当这个表被删除时,程序就会自动执行触发器里面定义的操作过程。这个就是删除表的操作就是触发器执行的条件了。
2、 在一个表中定义了行级的触发器,那当这个表中一行数据发生变化的时候,比如删除了一行记录,那触发器也会被自动执行了。
二、触发器语法
触发器的语法:
create [or replace] tigger 触发器名 触发时间 触发事件
[for each row]
&pl/sql语句
触发器名:触发器对象的名称。由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。
触发时间:指明触发器何时执行,该值可取:
before:表示在数据库动作之前触发器执行;
after:表示在数据库动作之后触发器执行。
触发事件:指明哪些数据库动作会触发此触发器:
insert:数据库插入会触发此触发器;
update:数据库修改会触发此触发器;
delete:数据库删除会触发此触发器。
表 名:数据库触发器所在的表。
for each row:对表的每一行触发器执行一次。如果没有这一选项,则只对整个表执行一次。
触发器能实现如下功能:
1、 允许/限制对表的修改
2、 自动生成派生列,比如自增字段
3、 强制数据一致性
4、 提供审计和日志记录
5、 防止无效的事务处理
6、 启用复杂的业务逻辑
1)、下面的触发器在更新表tb_emp之前触发,目的是不允许在周末修改表:
create or replace trigger auth_secure before insert or update or DELETE
&&IF(to_char(sysdate,'DY')='星期日') THEN
&&&&RAISE_APPLICATION_ERROR(-20600,'不能在周末修改表tb_emp');
2)、使用触发器实现序号自增
创建一个测试表:
create table tab_user(
&&id number(11) primary key,
&&username varchar(50),
&&password varchar(50)
创建一个序列:
复制代码 代码如下:
create sequence my_seq increment by 1 start with 1 nomaxvalue nocycle cache 20;
创建一个触发器:
CREATE OR REPLACE TRIGGER MY_TGR
&BEFORE INSERT ON TAB_USER
&FOR EACH ROW
&NEXT_ID NUMBER;
&SELECT MY_SEQ.NEXTVAL INTO NEXT_ID FROM DUAL;
&:NEW.ID := NEXT_ID;
向表插入数据:
insert into tab_user(username,password) values('admin','admin');
insert into tab_user(username,password) values('fgz','fgz');
insert into tab_user(username,password) values('test','test');
查询表结果:SELECT * FROM TAB_USER;
3)、当用户对test表执行DML语句时,将相关信息记录到日志表
CREATE TABLE test(
&&t_id& NUMBER(4),
&&t_name VARCHAR2(20),
&&t_age NUMBER(2),
&&t_sex CHAR
CREATE TABLE test_log(
&&l_user& VARCHAR2(15),
&&l_type& VARCHAR2(15),
&&l_date& VARCHAR2(30)
创建触发器:
CREATE OR REPLACE TRIGGER TEST_TRIGGER
&AFTER DELETE OR INSERT OR UPDATE ON TEST
&V_TYPE TEST_LOG.L_TYPE%TYPE;
&IF INSERTING THEN
&&V_TYPE := 'INSERT';
&&DBMS_OUTPUT.PUT_LINE('记录已经成功插入,并已记录到日志');
&ELSIF UPDATING THEN
&&V_TYPE := 'UPDATE';
&&DBMS_OUTPUT.PUT_LINE('记录已经成功更新,并已记录到日志');
&ELSIF DELETING THEN
&&V_TYPE := 'DELETE';
&&DBMS_OUTPUT.PUT_LINE('记录已经成功删除,并已记录到日志');
&INSERT INTO TEST_LOG
&&(USER, V_TYPE, TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));
INSERT INTO test VALUES(101,'zhao',22,'M');
UPDATE test SET t_age = 30 WHERE t_id = 101;
DELETE test WHERE t_id = 101;
SELECT * FROM
SELECT * FROM test_
运行结果如下:
3)、创建触发器,它将映射emp表中每个部门的总人数和总工资
CREATE TABLE dept_sal AS
SELECT deptno, COUNT(empno) total_emp, SUM(sal) total_sal
FROM scott.emp
CREATE OR REPLACE TRIGGER EMP_INFO
&AFTER INSERT OR UPDATE OR DELETE ON scott.EMP
&CURSOR CUR_EMP IS
&&SELECT DEPTNO, COUNT(EMPNO) AS TOTAL_EMP, SUM(SAL) AS TOTAL_SAL FROM scott.EMP GROUP BY DEPTNO;
&DELETE DEPT_SAL;
&FOR V_EMP IN CUR_EMP LOOP
&&INSERT INTO DEPT_SAL
&&&(V_EMP.DEPTNO, V_EMP.TOTAL_EMP, V_EMP.TOTAL_SAL);
&END LOOP;
INSERT INTO emp(empno,deptno,sal) VALUES('123','10',10000);
SELECT * FROM dept_
DELETE EMP WHERE empno=123;
SELECT * FROM dept_
显示结果如下:
4)、创建触发器,用来记录表的删除数据
CREATE TABLE employee(
&&id& VARCHAR2(4) NOT NULL,
&&name VARCHAR2(15) NOT NULL,
&&age NUMBER(2)& NOT NULL,
&&sex CHAR NOT NULL
INSERT INTO employee VALUES('e101','zhao',23,'M');
INSERT INTO employee VALUES('e102','jian',21,'F');
CREATE TABLE old_employee AS SELECT * FROM
CREATE OR REPLACE TRIGGER TIG_OLD_EMP
&AFTER DELETE ON EMPLOYEE
&FOR EACH ROW
&INSERT INTO OLD_EMPLOYEE VALUES (:OLD.ID, :OLD.NAME, :OLD.AGE, :OLD.SEX);
SELECT * FROM old_
5)、创建触发器,利用视图插入数据
CREATE TABLE tab1 (tid NUMBER(4) PRIMARY KEY,tname VARCHAR2(20),tage NUMBER(2));
CREATE TABLE tab2 (tid NUMBER(4),ttel VARCHAR2(15),tadr VARCHAR2(30));
INSERT INTO tab1 VALUES(101,'zhao',22);
INSERT INTO tab1 VALUES(102,'yang',20);
INSERT INTO tab2 VALUES(101,'','AnHuiSuZhou');
INSERT INTO tab2 VALUES(102,'','AnHuiSuZhou');
CREATE OR REPLACE VIEW tab_view AS SELECT tab1.tid,tname,ttel,tadr FROM tab1,tab2 WHERE tab1.tid = tab2.
CREATE OR REPLACE TRIGGER TAB_TRIGGER
&INSTEAD OF INSERT ON TAB_VIEW
&INSERT INTO TAB1 (TID, TNAME) VALUES (:NEW.TID, :NEW.TNAME);
&INSERT INTO TAB2 (TTEL, TADR) VALUES (:NEW.TTEL, :NEW.TADR);
INSERT INTO tab_view VALUES(106,'ljq','','beijing');
SELECT * FROM tab_
SELECT * FROM tab1;
SELECT * FROM tab2;
6)、创建触发器,比较emp表中更新的工资
set serveroutput on;
CREATE OR REPLACE TRIGGER SAL_EMP
&BEFORE UPDATE ON EMP
&FOR EACH ROW
&IF :OLD.SAL & :NEW.SAL THEN
&&DBMS_OUTPUT.PUT_LINE('工资减少');
&ELSIF :OLD.SAL & :NEW.SAL THEN
&&DBMS_OUTPUT.PUT_LINE('工资增加');
&&DBMS_OUTPUT.PUT_LINE('工资未作任何变动');
&DBMS_OUTPUT.PUT_LINE('更新前工资 :' || :OLD.SAL);
&DBMS_OUTPUT.PUT_LINE('更新后工资 :' || :NEW.SAL);
UPDATE emp SET sal = 3000 WHERE empno = '7788';
运行结果如下:
7)、创建触发器,将操作CREATE、DROP存储在log_info表
CREATE TABLE log_info(
&&manager_user VARCHAR2(15),
&&manager_date VARCHAR2(15),
&&manager_type VARCHAR2(15),
&&obj_name&& VARCHAR2(15),
&&obj_type&& VARCHAR2(15)
set serveroutput on;
CREATE OR REPLACE TRIGGER TRIG_LOG_INFO
&AFTER CREATE OR DROP ON SCHEMA
&INSERT INTO LOG_INFO
&&&SYSDATE,
&&&SYS.DICTIONARY_OBJ_NAME,
&&&SYS.DICTIONARY_OBJ_OWNER,
&&&SYS.DICTIONARY_OBJ_TYPE);
CREATE TABLE a(id NUMBER);
CREATE TYPE aa AS OBJECT(id NUMBER);
DROP TABLE a;
SELECT * FROM log_
SELECT * FROM USER_TRIGGERS;
SELECT * FROM ALL_TRIGGERS;SELECT * FROM DBA_TRIGGERS;
ALTER TRIGGER trigger_name DISABLE;
ALTER TRIGGER trigger_name ENABLE;
希望本文所述对大家Oracle数据库程序设计有所帮助。
阅读(...) 评论()你的浏览器禁用了JavaScript, 请开启后刷新浏览器获得更好的体验!
各种框架,架构的官方翻译文档!
Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。
发表了文章 o 0 个评论 o 10 次浏览 o
o 来自相关话题
发表了文章 o 0 个评论 o 8 次浏览 o
o 来自相关话题
发表了文章 o 0 个评论 o 10 次浏览 o
o 来自相关话题
发表了文章 o 0 个评论 o 14 次浏览 o
o 来自相关话题
SpringApplication类提供了一种简便的方式来从main()方法引导启动的Spring应用程序。在许多情况下,您可以委托给静态SpringApplication.run方法,如下例所示:public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class, args);
当您的应用程序启动时,您应该看到类似于以下输出的内容:
/\\ / ___'_ __ _ _(_)_ __
__ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
___)| |_)| | | | | || (_| |
|____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::
v2.0.4.RELEASE
00:08:16.117
INFO 56603 --- [
main] o.s.b.s.app.SampleApplication
: Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
00:08:16.166
INFO 56603 --- [
main] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
13:09:54.912
INFO 41370 --- [
main] .t.TomcatServletWebServerFactory : Server initialized with port: 8080
13:09:56.501
INFO 41370 --- [
main] o.s.b.s.app.SampleApplication
: Started SampleApplication in 2.992 seconds (JVM running for 3.658)
默认情况下,会显示日志INFO日志消息,包括一些相关的启动详细信息,例如启动应用程序的用户。如果您需要其他日志级别,则可以进行设置,详见 SpringBoot 2.0.X官方文档-013-日志记录
如果您的应用程序启动失败,注册的故障分析(FailureAnalyzers)程序将有机会提供专用的错误消息和解决问题的具体操作。例如,如果您在端口8080上启动一个web应用程序,并且该端口已经在使用,那么您应该看到以下消息类似的内容:***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
Spring Boot提供了许多FailureAnalyzer实现,您可以添加自己的实现。
如果没有故障分析器能够处理异常,您仍然可以显示完整的情况报告,以便更好地理解错误。为此,需要启用debug属性或为org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener启用调试日志记录。
例如,如果您使用java -jar运行应用程序,则可以按如下方式启用debug属性:$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
自定义横幅(Banner)
可以通过在您的类路径中添加一个 banner.txt 文件,或者将banner.location设置到banner文件的位置来更改启动时打印的banner。 如果文件有一些不常用的编码,你可以设置banner.charset(默认为UTF-8)。除了文本文件,您还可以将banner.gif,banner.jpg或banner.png图像文件添加到您的类路径中,或者设置一个banner.image.location属性。 图像将被转换成ASCII艺术表现,并打印在任何文字banner上方。
您可以在banner.txt文件中使用以下占位符:变量描述${application.version}在MANIFEST.MF中声明的应用程序的版本号。例如, Implementation-Version: 1.0 被打印为 1.0${application.formatted-version}在MANIFEST.MF中声明的应用程序版本号的格式化显示(用括号括起来,以v为前缀)。 例如 (v1.0)。${spring-boot.version}您正在使用的Spring Boot版本。 例如2.0.4.RELEASE${spring-boot.formatted-version}您正在使用的Spring Boot版本,格式化显示(用括号括起来并带有前缀v)。例如(v2.0.4.RELEASE)。{AnsiColor.NAME}, {AnsiStyle.NAME})其中NAME是ANSI转义码的名称。 有关详细信息,请参阅 AnsiPropertySource。${application.title}您的应用程序的标题在MANIFEST.MF中声明。 例如Implementation-Title:MyApp打印为MyApp。
如果要以编程方式生成banner,则可以使用SpringApplication.setBanner()方法。 使用org.springframework.boot.Banner 如接口,并实现自己的printBanner() 方法。
您还可以使用spring.main.banner-mode属性来决定是否必须在System.out(控制台)上打印banner,使用配置的logger(log)或不打印(off)。
打印的横幅被注册为一个单例bean,名称如下:springBootBanner。
YAML映射为false,所以如果要禁用应用程序中的banner,请务必添加引号,如下例所示:spring:
banner-mode: &off&
自定义SpringApplication
如果SpringApplication默认值不符合您的需要,您可以改为创建本地实例并对其进行自定义。例如,要关闭banner,您可以写:public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
传递给SpringApplication的构造函数参数是spring bean的配置源。 在大多数情况下,这些将引用@Configuration类,但它们也可以引用XML配置或应扫描的包。
也可以使用application.properties文件配置SpringApplication。 有关详细信息,请参见SpringBoot 2.0.X官方文档-011-外部配置。
有关配置选项的完整列表,请参阅SpringApplication Javadoc。
Fluent Builder API
如果您需要构建一个ApplicationContext层次结构(具有父/子关系的多个上下文),或者如果您只想使用“流式(fluent)”构建器API,则可以使用SpringApplicationBuilder。
SpringApplicationBuilder允许您将多个方法调用链接在一起,并包含父方法和子方法,它们允许您创建层次结构,如下例所示:new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
创建ApplicationContext层次结构时存在一些限制。例如,Web组件必须包含在子上下文中,并且Environment父组件和子上下文都使用相同的 组件。有关详细信息,请参阅SpringApplicationBuilder Javadoc。
Application events and listeners
除了通常的Spring Framework事件之外,例如 ContextRefreshedEvent,SpringApplication发送一些额外的应用程序事件。
在创建ApplicationContext之前,实际上触发了一些事件,因此您不能在@Bean上注册一个监听器。 您可以通过SpringApplication.addListeners(…) 或SpringApplicationBuilder.listeners(…)方法注册它们。
如果您希望自动注册这些侦听器,无论创建应用程序的方式如何,都可以将META-INF / spring.factories文件添加到项目中,并使用org.springframework.context.ApplicationListener引用您的侦听器。
org.springframework.context.ApplicationListener=com.example.project.MyListener
当应用程序运行时,应用程序事件按以下顺序发送:
ApplicationStartingEvent在运行开始时发送,但在任何处理之前发送,除了侦听器和初始化器的注册之外。当要在上下文中使用的环境已知但在创建上下文之前已知时,将发送ApplicationEnvironmentPreparedEvent。ApplicationPreparedEvent是在刷新启动之前发送的,但在bean定义加载之后。一个ApplicationStartedEvent是在上下文刷新之后,但在调用任何应用程序和命令行运行程序之前发送的。在调用任何应用程序和命令行运行程序之后发送ApplicationReadyEvent。它表明应用程序已经准备好为请求提供服务。如果启动时出现异常,将发送ApplicationFailedEvent。
一般您不需要使用应用程序事件,但可以方便地知道它们存在。 在内部,Spring Boot使用事件来处理各种任务。
应用程序事件通过Spring框架的事件发布机制发送。这种机制的一部分确保在子上下文中发布给侦听器的事件也在任何上下文中发布给侦听器。因此,如果您的应用程序使用SpringApplication实例的层次结构,那么侦听器可能会接收到相同类型的应用程序事件的多个实例。
为了让侦听器区分上下文事件和子代上下文事件,它应该请求注入其应用程序上下文,然后将注入的上下文与事件上下文进行比较。可以通过实现ApplicationContextAware或(如果侦听器是bean)使用@Autowired来注入上下文。
SpringApplication尝试为您创建正确类型的ApplicationContext。用于确定WebApplicationType的算法相当简单:
如果有Spring MVC,就会使用AnnotationConfigServletWebServerApplicationContext如果没有Spring MVC,并且有Spring WebFlux,那么就使用AnnotationConfigReactiveWebServerApplicationContext否则,使用AnnotationConfigApplicationContext
这意味着如果您在同一个应用程序中使用Spring MVC和Spring WebFlux的新WebClient, Spring MVC将被默认使用。您可以通过调用setWebApplicationType(WebApplicationType)来轻松地覆盖它。
也可以完全控制调用setApplicationContextClass(…)时使用的ApplicationContext类型。
在JUnit测试中使用SpringApplication时,通常需要调用setWebApplicationType(WebApplicationType.NONE)。
访问应用程序参数
如果需要访问传递给SpringApplication.run(…)的应用程序参数,可以注入org.springframework.boot。ApplicationArguments bean。ApplicationArguments接口提供了对原始字符串[]参数以及解析选项和非选项参数的访问,如下例所示:import org.springframework.boot.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;
@Component
public class MyBean {
@Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption(&debug&);
List&String& files = args.getNonOptionArgs();
// if run with &--debug logfile.txt& debug=true, files=[&logfile.txt&]
Spring Boot还在Spring环境中注册了CommandLinePropertySource。这允许您通过使用@Value注释注入单个应用程序参数。
使用ApplicationRunner或CommandLineRunner
如果您需要在SpringApplication启动后运行一些特定的代码,您可以实现ApplicationRunner或CommandLineRunner接口。这两个接口以相同的方式工作,并提供一个运行方法,该方法在SpringApplication.run(…)完成之前调用。
CommandLineRunner接口以简单的字符串数组的形式提供对应用程序参数的访问,而ApplicationRunner使用前面讨论的ApplicationArguments接口。下面的例子展示了一个带有run方法的CommandLineRunner:import org.springframework.boot.*;
import org.springframework.stereotype.*;
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
如果定义了几个CommandLineRunner或ApplicationRunner bean,必须按特定顺序调用,则可以另外实现org.springframework.core.Ordered的接口或使用org.springframework.core.annotation.Order 注解。
Application退出
每个SpringApplication都向JVM注册一个关闭钩子,以确保ApplicationContext在退出时优雅地关闭。所有标准的Spring生命周期回调(例如DisposableBean接口或@PreDestroy注释)都可以使用。
此外,bean可以实现org.springframework.boot.ExitCodeGenerator接口(如果它们希望在调用SpringApplication.exit()时返回特定的退出代码)。然后,可以将此退出代码传递给System.exit(),以将其作为状态代码返回,如下例所示:@SpringBootApplication
public class ExitCodeApplication {
public ExitCodeGenerator exitCodeGenerator() {
return () -& 42;
public static void main(String[] args) {
System.exit(SpringApplication
.exit(SpringApplication.run(ExitCodeApplication.class, args)));
另外,ExitCodeGenerator接口也可以由异常实现。当遇到这种异常时,Spring Boot返回由实现的getExitCode()方法提供的退出代码。
通过指定spring.application.admin.enabled可以为应用程序启用管理相关的特性。这将在MBeanServer平台上公开SpringApplicationAdminMXBean。您可以使用这个特性远程管理Spring应用程序。这个特性对于任何服务包装器实现都是有用的。
如果您想知道应用程序在哪个HTTP端口上运行,请使用local.server.port获取属性。
在启用这个特性时要小心,因为MBean公开了一个关闭应用程序的方法。
SpringApplication类提供了一种简便的方式来从main()方法引导启动的Spring应用程序。在许多情况下,您可以委托给静态SpringApplication.run方法,如下例所示:public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class, args);
当您的应用程序启动时,您应该看到类似于以下输出的内容:
/\\ / ___'_ __ _ _(_)_ __
__ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
___)| |_)| | | | | || (_| |
|____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::
v2.0.4.RELEASE
00:08:16.117
INFO 56603 --- [
main] o.s.b.s.app.SampleApplication
: Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
00:08:16.166
INFO 56603 --- [
main] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
13:09:54.912
INFO 41370 --- [
main] .t.TomcatServletWebServerFactory : Server initialized with port: 8080
13:09:56.501
INFO 41370 --- [
main] o.s.b.s.app.SampleApplication
: Started SampleApplication in 2.992 seconds (JVM running for 3.658)
默认情况下,会显示日志INFO日志消息,包括一些相关的启动详细信息,例如启动应用程序的用户。如果您需要其他日志级别,则可以进行设置,详见
如果您的应用程序启动失败,注册的故障分析(FailureAnalyzers)程序将有机会提供专用的错误消息和解决问题的具体操作。例如,如果您在端口8080上启动一个web应用程序,并且该端口已经在使用,那么您应该看到以下消息类似的内容:***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
Spring Boot提供了许多FailureAnalyzer实现,您可以。
如果没有故障分析器能够处理异常,您仍然可以显示完整的情况报告,以便更好地理解错误。为此,需要启用debug属性或为org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener启用调试日志记录。
例如,如果您使用java -jar运行应用程序,则可以按如下方式启用debug属性:$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
自定义横幅(Banner)
可以通过在您的类路径中添加一个 banner.txt 文件,或者将banner.location设置到banner文件的位置来更改启动时打印的banner。 如果文件有一些不常用的编码,你可以设置banner.charset(默认为UTF-8)。除了文本文件,您还可以将banner.gif,banner.jpg或banner.png图像文件添加到您的类路径中,或者设置一个banner.image.location属性。 图像将被转换成ASCII艺术表现,并打印在任何文字banner上方。
您可以在banner.txt文件中使用以下占位符:变量描述${application.version}在MANIFEST.MF中声明的应用程序的版本号。例如, Implementation-Version: 1.0 被打印为 1.0${application.formatted-version}在MANIFEST.MF中声明的应用程序版本号的格式化显示(用括号括起来,以v为前缀)。 例如 (v1.0)。${spring-boot.version}您正在使用的Spring Boot版本。 例如2.0.4.RELEASE${spring-boot.formatted-version}您正在使用的Spring Boot版本,格式化显示(用括号括起来并带有前缀v)。例如(v2.0.4.RELEASE)。{AnsiColor.NAME}, {AnsiStyle.NAME})其中NAME是ANSI转义码的名称。 有关详细信息,请参阅 。${application.title}您的应用程序的标题在MANIFEST.MF中声明。 例如Implementation-Title:MyApp打印为MyApp。
如果要以编程方式生成banner,则可以使用SpringApplication.setBanner()方法。 使用org.springframework.boot.Banner 如接口,并实现自己的printBanner() 方法。
您还可以使用spring.main.banner-mode属性来决定是否必须在System.out(控制台)上打印banner,使用配置的logger(log)或不打印(off)。
打印的横幅被注册为一个单例bean,名称如下:springBootBanner。
YAML映射为false,所以如果要禁用应用程序中的banner,请务必添加引号,如下例所示:spring:
banner-mode: &off&
自定义SpringApplication
如果SpringApplication默认值不符合您的需要,您可以改为创建本地实例并对其进行自定义。例如,要关闭banner,您可以写:public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
传递给SpringApplication的构造函数参数是spring bean的配置源。 在大多数情况下,这些将引用@Configuration类,但它们也可以引用XML配置或应扫描的包。
也可以使用application.properties文件配置SpringApplication。 有关详细信息,请参见。
有关配置选项的完整列表,请参阅。
Fluent Builder API
如果您需要构建一个ApplicationContext层次结构(具有父/子关系的多个上下文),或者如果您只想使用“流式(fluent)”构建器API,则可以使用SpringApplicationBuilder。
SpringApplicationBuilder允许您将多个方法调用链接在一起,并包含父方法和子方法,它们允许您创建层次结构,如下例所示:new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
创建ApplicationContext层次结构时存在一些限制。例如,Web组件必须包含在子上下文中,并且Environment父组件和子上下文都使用相同的 组件。有关详细信息,请参阅。
Application events and listeners
除了通常的Spring Framework事件之外,例如 ,SpringApplication发送一些额外的应用程序事件。
在创建ApplicationContext之前,实际上触发了一些事件,因此您不能在@Bean上注册一个监听器。 您可以通过SpringApplication.addListeners(…) 或SpringApplicationBuilder.listeners(…)方法注册它们。
如果您希望自动注册这些侦听器,无论创建应用程序的方式如何,都可以将META-INF / spring.factories文件添加到项目中,并使用org.springframework.context.ApplicationListener引用您的侦听器。
org.springframework.context.ApplicationListener=com.example.project.MyListener
当应用程序运行时,应用程序事件按以下顺序发送:
ApplicationStartingEvent在运行开始时发送,但在任何处理之前发送,除了侦听器和初始化器的注册之外。当要在上下文中使用的环境已知但在创建上下文之前已知时,将发送ApplicationEnvironmentPreparedEvent。ApplicationPreparedEvent是在刷新启动之前发送的,但在bean定义加载之后。一个ApplicationStartedEvent是在上下文刷新之后,但在调用任何应用程序和命令行运行程序之前发送的。在调用任何应用程序和命令行运行程序之后发送ApplicationReadyEvent。它表明应用程序已经准备好为请求提供服务。如果启动时出现异常,将发送ApplicationFailedEvent。
一般您不需要使用应用程序事件,但可以方便地知道它们存在。 在内部,Spring Boot使用事件来处理各种任务。
应用程序事件通过Spring框架的事件发布机制发送。这种机制的一部分确保在子上下文中发布给侦听器的事件也在任何上下文中发布给侦听器。因此,如果您的应用程序使用SpringApplication实例的层次结构,那么侦听器可能会接收到相同类型的应用程序事件的多个实例。
为了让侦听器区分上下文事件和子代上下文事件,它应该请求注入其应用程序上下文,然后将注入的上下文与事件上下文进行比较。可以通过实现ApplicationContextAware或(如果侦听器是bean)使用@Autowired来注入上下文。
SpringApplication尝试为您创建正确类型的ApplicationContext。用于确定WebApplicationType的算法相当简单:
如果有Spring MVC,就会使用AnnotationConfigServletWebServerApplicationContext如果没有Spring MVC,并且有Spring WebFlux,那么就使用AnnotationConfigReactiveWebServerApplicationContext否则,使用AnnotationConfigApplicationContext
这意味着如果您在同一个应用程序中使用Spring MVC和Spring WebFlux的新WebClient, Spring MVC将被默认使用。您可以通过调用setWebApplicationType(WebApplicationType)来轻松地覆盖它。
也可以完全控制调用setApplicationContextClass(…)时使用的ApplicationContext类型。
在JUnit测试中使用SpringApplication时,通常需要调用setWebApplicationType(WebApplicationType.NONE)。
访问应用程序参数
如果需要访问传递给SpringApplication.run(…)的应用程序参数,可以注入org.springframework.boot。ApplicationArguments bean。ApplicationArguments接口提供了对原始字符串[]参数以及解析选项和非选项参数的访问,如下例所示:import org.springframework.boot.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;
@Component
public class MyBean {
@Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption(&debug&);
List&String& files = args.getNonOptionArgs();
// if run with &--debug logfile.txt& debug=true, files=[&logfile.txt&]
Spring Boot还在Spring环境中注册了CommandLinePropertySource。这允许您通过使用@Value注释注入单个应用程序参数。
使用ApplicationRunner或CommandLineRunner
如果您需要在SpringApplication启动后运行一些特定的代码,您可以实现ApplicationRunner或CommandLineRunner接口。这两个接口以相同的方式工作,并提供一个运行方法,该方法在SpringApplication.run(…)完成之前调用。
CommandLineRunner接口以简单的字符串数组的形式提供对应用程序参数的访问,而ApplicationRunner使用前面讨论的ApplicationArguments接口。下面的例子展示了一个带有run方法的CommandLineRunner:import org.springframework.boot.*;
import org.springframework.stereotype.*;
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
如果定义了几个CommandLineRunner或ApplicationRunner bean,必须按特定顺序调用,则可以另外实现org.springframework.core.Ordered的接口或使用org.springframework.core.annotation.Order 注解。
Application退出
每个SpringApplication都向JVM注册一个关闭钩子,以确保ApplicationContext在退出时优雅地关闭。所有标准的Spring生命周期回调(例如DisposableBean接口或@PreDestroy注释)都可以使用。
此外,bean可以实现org.springframework.boot.ExitCodeGenerator接口(如果它们希望在调用SpringApplication.exit()时返回特定的退出代码)。然后,可以将此退出代码传递给System.exit(),以将其作为状态代码返回,如下例所示:@SpringBootApplication
public class ExitCodeApplication {
public ExitCodeGenerator exitCodeGenerator() {
return () -& 42;
public static void main(String[] args) {
System.exit(SpringApplication
.exit(SpringApplication.run(ExitCodeApplication.class, args)));
另外,ExitCodeGenerator接口也可以由异常实现。当遇到这种异常时,Spring Boot返回由实现的getExitCode()方法提供的退出代码。
通过指定spring.application.admin.enabled可以为应用程序启用管理相关的特性。这将在MBeanServer平台上公开SpringApplicationAdminMXBean。您可以使用这个特性远程管理Spring应用程序。这个特性对于任何服务包装器实现都是有用的。
如果您想知道应用程序在哪个HTTP端口上运行,请使用local.server.port获取属性。
在启用这个特性时要小心,因为MBean公开了一个关闭应用程序的方法。
发表了文章 o 0 个评论 o 7 次浏览 o
o 来自相关话题
本文将重点介绍如何使用Spring Rest中的ETag, REST API的集成测试以及使用curl的消费方案。
REST和ETags
关于ETag支持的官方Spring文档:
ETag(实体标签)是HTTP/1.1兼容的web服务器返回的HTTP响应头,用于确定给定URL的内容更改。
ETags用于两件事——缓存和条件请求。ETag值可以是一个从响应主体的字节中计算出来的哈希值。因为可能会使用加密散列函数,所以即使对主体进行最小的修改,也会彻底改变输出,从而改变ETag的值。这只适用于强ETags——协议也提供弱Etag。
使用If-* header将标准GET请求转换为条件GET。与ETags一起使用的两个If-*header是If-None-Match和If-Match—正如本文后面讨论的那样,每个标头都有自己的语义。
使用curl客户端与服务器通信
一个包含ETags的简单的客户端-服务器通信可以分解为以下步骤:
首先,客户端进行REST API调用 - 响应包括要存储以供进一步使用的ETag标头:curl -H &Accept: application/json& -i http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 200 OKETag: &f88dd058fef01be66a7&Content-Type: application/charset=UTF-8Content-Length: 52客户端对REST API的下一个请求包括从上一步中获得ETag值的If-None-Match请求标头;如果服务器上的资源没有更改,则响应将不包含任何正文和304的状态码—Not Modified:curl -H &Accept: application/json& -H 'If-None-Match: &f88dd058fef01be66a7&' -i http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 304 Not ModifiedETag: &f88dd058fef01be66a7&现在,在再次检索资源之前,我们将通过执行更新来更改它:curl --user :adminpass -H &Content-Type: application/json& -i
-X PUT --data '{ &id&:1, &name&:&newRoleName2&, &description&:&theNewDescription& }'
http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 200 OKETag: &d41d8cd98f00b204e9800998ecf8427e&Content-Length: 0最后,我们再次发出最后一次检索权限的请求; 请记住,自上次检索以来它已被更新,因此之前的ETag值不再有效 - 响应将包含新数据和新的ETag,再次可以存储以供进一步使用:curl -H &Accept: application/json& -H 'If-None-Match: &f88dd058fef01be66a7&' -i
http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 200 OKETag: &03cb37cac0aad4cb04c3a211&Content-Type: application/charset=UTF-8Content-Length: 56Spring对ETag的支持在Spring支持上—在Spring中使用ETag非常容易设置,对于应用程序完全透明。支持是通过在web.xml中添加一个简单的过滤器来实现的。&filter&
&filter-name&etagFilter&/filter-name&
&filter-class&org.springframework.web.filter.ShallowEtagHeaderFilter&/filter-class&&/filter&&filter-mapping&
&filter-name&etagFilter&/filter-name&
&url-pattern&/api/*&/url-pattern&&/filter-mapping&过滤器映射到与RESTful API本身相同的URI模式上。过滤器本身是自Spring 3.0以来ETag功能的标准实现。该实现是一个浅显的实现—ETag是基于响应计算的,这将节省带宽,而不是服务器性能。因此,从ETag支持中受益的请求仍将作为标准请求进行处理,消耗它通常使用的任何资源(数据库连接等),只有在将响应返回给客户端之前,ETag支持才会启动。此时,ETag将从Response主体计算出来并设置在Resource本身上; 另外,如果在Request上设置了If-None-Match标头,它也将被处理。ETag的更深层次的实现机制可能会提供更大的好处,比如一些服务请求从缓存中并没有执行计算,但是实现将绝对不是那么简单。测试ETag让我们开始简单 - 我们需要验证检索单个资源的简单请求的响应是否会实际返回“ ETag”标头:@Testpublic void givenResourceExists_whenRetrievingResource_thenEtagIsAlsoReturned() {
String uriOfResource = createAsUri();
Response findOneResponse = RestAssured.given().header(&Accept&, &application/json&).get(uriOfResource);
assertNotNull(findOneResponse.getHeader(&ETag&));}接下来,我们验证ETag行为的路径 - 如果从服务器检索资源的请求使用正确的ETag值,则不再返回资源。@Testpublic void givenResourceWasRetrieved_whenRetrievingAgainWithEtag_thenNotModifiedReturned() {
String uriOfResource = createAsUri();
Response findOneResponse = RestAssured.given().
header(&Accept&, &application/json&).get(uriOfResource);
String etagValue = findOneResponse.getHeader(HttpHeaders.ETAG);
Response secondFindOneResponse= RestAssured.given().
header(&Accept&, &application/json&).headers(&If-None-Match&, etagValue)
.get(uriOfResource);
assertTrue(secondFindOneResponse.getStatusCode() == 304);}首先创建资源,然后检索—ETag值被存储以供进一步使用发送新的检索请求,这次使用“ If-None-Match ”标头指定先前存储的ETag值在第二个请求中,服务器只返回304 Not Modified,因为资源本身确实没有在两个检索操作之间进行修改最后,我们验证在第一个和第二个检索请求之间更改资源的情况:@Testpublic void
givenResourceWasRetrievedThenModified_whenRetrievingAgainWithEtag_thenResourceIsReturned() {
String uriOfResource = createAsUri();
Response findOneResponse = RestAssured.given().
header(&Accept&, &application/json&).get(uriOfResource);
String etagValue = findOneResponse.getHeader(HttpHeaders.ETAG);
existingResource.setName(randomAlphabetic(6));
update(existingResource);
Response secondFindOneResponse= RestAssured.given().
header(&Accept&, &application/json&).headers(&If-None-Match&, etagValue)
.get(uriOfResource);
assertTrue(secondFindOneResponse.getStatusCode() == 200);}首先创建资源,然后检索—ETag值被存储以供进一步使用然后更新相同的资源发送新的检索请求,这次使用“ If-None-Match ”标头指定先前存储的ETag值在第二个请求中,服务器将返回200 OK以及完整的资源,因为ETag值不再正确,因为资源已在此期间更新最后一个测试是对If-Match HTTP报头的支持,因为这个功能在Spring中还没有实现,所以这个测试不会成功:@Testpublic void givenResourceExists_whenRetrievedWithIfMatchIncorrectEtag_then412IsReceived() {
T existingResource = getApi().create(createNewEntity());
String uriOfResource = baseUri + &/& + existingResource.getId();
Response findOneResponse = RestAssured.given().header(&Accept&, &application/json&).
headers(&If-Match&, randomAlphabetic(8)).get(uriOfResource);
assertTrue(findOneResponse.getStatusCode() == 412);}首先创建资源然后使用“ If-Match ”标头检索资源,指定不正确的ETag值 - 这是条件GET请求服务器应返回412 Precondition Failed
我们只使用ETag进行读操作 - 一个RFC试图实现如何处理写操作上的ETag。
当然还有ETag的其他用途,例如使用Spring 3.1的乐观锁定机制以及处理相关的丢失更新问题。
本文重点介绍了如何使用Spring Rest中的ETag。
本文将重点介绍如何使用Spring Rest中的ETag, REST API的集成测试以及使用curl的消费方案。
REST和ETags
关于ETag支持的官方Spring文档:
(实体标签)是HTTP/1.1兼容的web服务器返回的HTTP响应头,用于确定给定URL的内容更改。
ETags用于两件事——缓存和条件请求。ETag值可以是一个从响应主体的字节中计算出来的哈希值。因为可能会使用加密散列函数,所以即使对主体进行最小的修改,也会彻底改变输出,从而改变ETag的值。这只适用于强ETags——协议也提供。
使用If-* header将标准GET请求转换为条件GET。与ETags一起使用的两个If-*header是和—正如本文后面讨论的那样,每个标头都有自己的语义。
使用curl客户端与服务器通信
一个包含ETags的简单的客户端-服务器通信可以分解为以下步骤:
首先,客户端进行REST API调用 - 响应包括要存储以供进一步使用的ETag标头:curl -H &Accept: application/json& -i http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 200 OKETag: &f88dd058fef01be66a7&Content-Type: application/charset=UTF-8Content-Length: 52客户端对REST API的下一个请求包括从上一步中获得ETag值的If-None-Match请求标头;如果服务器上的资源没有更改,则响应将不包含任何正文和304的状态码—Not Modified:curl -H &Accept: application/json& -H 'If-None-Match: &f88dd058fef01be66a7&' -i http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 304 Not ModifiedETag: &f88dd058fef01be66a7&现在,在再次检索资源之前,我们将通过执行更新来更改它:curl --user :adminpass -H &Content-Type: application/json& -i
-X PUT --data '{ &id&:1, &name&:&newRoleName2&, &description&:&theNewDescription& }'
http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 200 OKETag: &d41d8cd98f00b204e9800998ecf8427e&Content-Length: 0最后,我们再次发出最后一次检索权限的请求; 请记住,自上次检索以来它已被更新,因此之前的ETag值不再有效 - 响应将包含新数据和新的ETag,再次可以存储以供进一步使用:curl -H &Accept: application/json& -H 'If-None-Match: &f88dd058fef01be66a7&' -i
http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 200 OKETag: &03cb37cac0aad4cb04c3a211&Content-Type: application/charset=UTF-8Content-Length: 56Spring对ETag的支持在Spring支持上—在Spring中使用ETag非常容易设置,对于应用程序完全透明。支持是通过在web.xml中添加一个简单的过滤器来实现的。&filter&
&filter-name&etagFilter&/filter-name&
&filter-class&org.springframework.web.filter.ShallowEtagHeaderFilter&/filter-class&&/filter&&filter-mapping&
&filter-name&etagFilter&/filter-name&
&url-pattern&/api/*&/url-pattern&&/filter-mapping&过滤器映射到与RESTful API本身相同的URI模式上。过滤器本身是自Spring 3.0以来ETag功能的标准实现。该实现是一个浅显的实现—ETag是基于响应计算的,这将节省带宽,而不是服务器性能。因此,从ETag支持中受益的请求仍将作为标准请求进行处理,消耗它通常使用的任何资源(数据库连接等),只有在将响应返回给客户端之前,ETag支持才会启动。此时,ETag将从Response主体计算出来并设置在Resource本身上; 另外,如果在Request上设置了If-None-Match标头,它也将被处理。ETag的更深层次的实现机制可能会提供更大的好处,比如一些服务请求从缓存中并没有执行计算,但是实现将绝对不是那么简单。测试ETag让我们开始简单 - 我们需要验证检索单个资源的简单请求的响应是否会实际返回“ ETag”标头:@Testpublic void givenResourceExists_whenRetrievingResource_thenEtagIsAlsoReturned() {
String uriOfResource = createAsUri();
Response findOneResponse = RestAssured.given().header(&Accept&, &application/json&).get(uriOfResource);
assertNotNull(findOneResponse.getHeader(&ETag&));}接下来,我们验证ETag行为的路径 - 如果从服务器检索资源的请求使用正确的ETag值,则不再返回资源。@Testpublic void givenResourceWasRetrieved_whenRetrievingAgainWithEtag_thenNotModifiedReturned() {
String uriOfResource = createAsUri();
Response findOneResponse = RestAssured.given().
header(&Accept&, &application/json&).get(uriOfResource);
String etagValue = findOneResponse.getHeader(HttpHeaders.ETAG);
Response secondFindOneResponse= RestAssured.given().
header(&Accept&, &application/json&).headers(&If-None-Match&, etagValue)
.get(uriOfResource);
assertTrue(secondFindOneResponse.getStatusCode() == 304);}首先创建资源,然后检索—ETag值被存储以供进一步使用发送新的检索请求,这次使用“ If-None-Match ”标头指定先前存储的ETag值在第二个请求中,服务器只返回304 Not Modified,因为资源本身确实没有在两个检索操作之间进行修改最后,我们验证在第一个和第二个检索请求之间更改资源的情况:@Testpublic void
givenResourceWasRetrievedThenModified_whenRetrievingAgainWithEtag_thenResourceIsReturned() {
String uriOfResource = createAsUri();
Response findOneResponse = RestAssured.given().
header(&Accept&, &application/json&).get(uriOfResource);
String etagValue = findOneResponse.getHeader(HttpHeaders.ETAG);
existingResource.setName(randomAlphabetic(6));
update(existingResource);
Response secondFindOneResponse= RestAssured.given().
header(&Accept&, &application/json&).headers(&If-None-Match&, etagValue)
.get(uriOfResource);
assertTrue(secondFindOneResponse.getStatusCode() == 200);}首先创建资源,然后检索—ETag值被存储以供进一步使用然后更新相同的资源发送新的检索请求,这次使用“ If-None-Match ”标头指定先前存储的ETag值在第二个请求中,服务器将返回200 OK以及完整的资源,因为ETag值不再正确,因为资源已在此期间更新最后一个测试是对If-Match HTTP报头的支持,因为这个功能在,所以这个测试不会成功:@Testpublic void givenResourceExists_whenRetrievedWithIfMatchIncorrectEtag_then412IsReceived() {
T existingResource = getApi().create(createNewEntity());
String uriOfResource = baseUri + &/& + existingResource.getId();
Response findOneResponse = RestAssured.given().header(&Accept&, &application/json&).
headers(&If-Match&, randomAlphabetic(8)).get(uriOfResource);
assertTrue(findOneResponse.getStatusCode() == 412);}首先创建资源然后使用“ If-Match ”标头检索资源,指定不正确的ETag值 - 这是条件GET请求服务器应返回412 Precondition Failed
我们只使用ETag进行读操作 - 一个试图实现如何处理写操作上的ETag。
当然还有ETag的其他用途,例如使用以及。
本文重点介绍了如何使用Spring Rest中的ETag。
发表了文章 o 0 个评论 o 18 次浏览 o
o 来自相关话题
Spring中文网为了方便大家及时获取技术文章,以及网站最新资讯,我们推出以下服务,欢迎大家踊跃关注。。。
Spring中文网官方微信公众号
Spring中文网官方QQ群
Spring中文网为了方便大家及时获取技术文章,以及网站最新资讯,我们推出以下服务,欢迎大家踊跃关注。。。
Spring中文网官方微信公众号
Spring中文网官方QQ群
发表了文章 o 0 个评论 o 13 次浏览 o
o 来自相关话题
在这篇文章中,我们简要概述了Spring @RequestBody和@ResponseBody注解。
@RequestBody
简单地说,@RequestBody注解将HttpRequest主体映射到传输或域对象,从而实现将入站HttpRequest主体自动反序列化到Java对象上。
首先,让我们看一下Spring控制器方法:@PostMapping(&/request&)
public ResponseEntity postController(
@RequestBody LoginForm loginForm) {
exampleService.fakeAuthenticate(loginForm);
return ResponseEntity.ok(HttpStatus.OK);
假设指定了适当的JSON,Spring会自动将JSON反序列化为Java类型。默认情况下,我们使用@RequestBody注解的类型必须与从客户端控制器发送的JSON相对应:public class LoginForm {
这里,我们用来表示HttpRequest主体的对象映射到我们的LoginForm对象。
让我们用CURL测试一下:curl -i \
-H &Accept: application/json& \
-H &Content-Type:application/json& \
-X POST --data
'{&username&: &johnny&, &password&: &password&}' &https://localhost:8080/.../request&
这就是使用@RequestBody注释的Spring REST API和客户端所需要的全部内容!
@ResponseBody
@ResponseBody注解告诉返回的对象将自动序列化为JSON,并通过回控制器的HttpResponse对象。
假设我们有一个自定义的Response对象:public class ResponseTransfer {
// standard getters/setters
接下来,可以实现相关的控制器:@Controller
@RequestMapping(&/post&)
public class ExamplePostController {
@Autowired
ExampleService exampleS
@PostMapping(&/response&)
@ResponseBody
public ResponseTransfer postResponseController(
@RequestBody LoginForm loginForm) {
return new ResponseTransfer(&Thanks For Posting!!!&);
在我们浏览器的开发者控制台中或使用像Postman这样的工具,我们可以看到以下响应:{&text&:&Thanks For Posting!!!&}
记住,我们不需要用@ResponseBody注解@Restcontroller注解的控制器,因为它在这里是默认的。
我们为Spring应用程序构建了一个简单的客户端,演示了如何使用@RestController和@ResponseBody注解。
在这篇文章中,我们简要概述了Spring @RequestBody和@ResponseBody注解。
@RequestBody
简单地说,@RequestBody注解将HttpRequest主体映射到传输或域对象,从而实现将入站HttpRequest主体自动反序列化到Java对象上。
首先,让我们看一下Spring控制器方法:@PostMapping(&/request&)
public ResponseEntity postController(
@RequestBody LoginForm loginForm) {
exampleService.fakeAuthenticate(loginForm);
return ResponseEntity.ok(HttpStatus.OK);
假设指定了适当的JSON,Spring会自动将JSON反序列化为Java类型。默认情况下,我们使用@RequestBody注解的类型必须与从客户端控制器发送的JSON相对应:public class LoginForm {
这里,我们用来表示HttpRequest主体的对象映射到我们的LoginForm对象。
让我们用CURL测试一下:curl -i \
-H &Accept: application/json& \
-H &Content-Type:application/json& \
-X POST --data
'{&username&: &johnny&, &password&: &password&}' &https://localhost:8080/.../request&
这就是使用@RequestBody注释的Spring REST API和客户端所需要的全部内容!
@ResponseBody
@ResponseBody注解告诉返回的对象将自动序列化为JSON,并通过回控制器的HttpResponse对象。
假设我们有一个自定义的Response对象:public class ResponseTransfer {
// standard getters/setters
接下来,可以实现相关的控制器:@Controller
@RequestMapping(&/post&)
public class ExamplePostController {
@Autowired
ExampleService exampleS
@PostMapping(&/response&)
@ResponseBody
public ResponseTransfer postResponseController(
@RequestBody LoginForm loginForm) {
return new ResponseTransfer(&Thanks For Posting!!!&);
在我们浏览器的开发者控制台中或使用像Postman这样的工具,我们可以看到以下响应:{&text&:&Thanks For Posting!!!&}
记住,我们不需要用@ResponseBody注解@Restcontroller注解的控制器,因为它在这里是默认的。
我们为Spring应用程序构建了一个简单的客户端,演示了如何使用@RestController和@ResponseBody注解。
发表了文章 o 0 个评论 o 8 次浏览 o
o 来自相关话题
Spring Boot包含一组开发工具,可以使应用程序开发体验更加愉快。spring-boot-devtools模块可以包含在任何项目中,以提供额外的开发功能。要包含devtools支持,请将模块依赖项添加到您的构建配置中,如以下Maven和Gradle列表所示:
Maven&dependencies&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-devtools&/artifactId&
&optional&true&/optional&
&/dependency&
&/dependencies&
Gradledependencies {
compile(&org.springframework.boot:spring-boot-devtools&)
在运行完全打包的应用程序时,会自动禁用开发工具。如果您的应用程序是从java -jar启动的,或者是从一个特殊的类加载程序启动的,那么它被认为是一个“(production application)生产应用程序”。将依赖项标记为Maven中的可选项或在Gradle中只使用compileOnly是防止devtools临时应用到使用项目的其他模块的最佳实践。
重新打包默认情况下不包含devtools。如果您想使用某个远程devtools特性,您需要禁用excludeDevtools build属性。Maven和Gradle插件都支持这个属性。
属性默认值
Spring Boot支持几个库使用缓存来提高性能。例如,模板引擎缓存已编译的模板以避免重复解析模板文件。此外,Spring MVC可以在提供静态资源时为响应添加HTTP缓存头。
虽然缓存在生产中非常有用,但在开发过程中可能会适得其反,从而使您无法看到刚刚在应用程序中进行的更改。因此,spring-boot-devtools默认禁用缓存选项。
缓存选项通常由application.properties文件中配置。例如,Thymeleaf提供该spring.thymeleaf.cache配置。spring-boot-devtools模块不需要手动设置这些属性,而是自动应用合理的开发时配置
有关devtools应用的属性的完整列表,请参阅 DevToolsPropertyDefaultsPostProcessor。
使用spring-boot-devtools的应用程序在类路径更改时自动重新启动。在IDE中工作时,这可能是一个有用的特性,因为它为代码更改提供了一个非常快速的反馈循环。默认情况下,指向文件夹的类路径中的任何条目都将受到监视,以查看是否有更改。注意,某些资源(如静态资产和视图模板)不需要重新启动应用程序。
由于DevTools监视类路径资源,因此触发重新启动的唯一方法是更新类路径。导致更新类路径的方式取决于您使用的IDE。在Eclipse中,保存修改后的文件会导致更新类路径并触发重新启动。在IntelliJ IDEA中,构建项目(Build -& Build Project)具有相同的效果。
只要启用了forking,您就可以使用支持的构建插件(Maven和Gradle)来启动应用程序,因为DevTools需要一个独立的应用程序类加载器才能正常运行。默认情况下,Gradle和Maven会在类路径上检测DevTools。
与LiveReload一起使用时,自动重启非常有效。 有关详细信息,请参阅LiveReload部分。如果使用JRebel,则禁用自动重新启动以支持动态类重新加载。其他devtools功能(例如LiveReload和属性覆盖)仍然可以使用。
DevTools依赖于应用程序上下文的关机挂钩在重新启动时关闭它。如果您已经禁用了关闭钩子(SpringApplication.setRegisterShutdownHook(false)),那么它将无法正常工作。
当决定是否在类路径中的条目应该触发重新启动时,DevTools自动忽略命名的项目spring-boot, spring-boot-devtools,spring-boot-autoconfigure,spring-boot-actuator,和spring-boot-starter。
DevTools需要自定义ResourceLoader使用的ApplicationContext。如果您的应用程序已经提供了一个,它将被打包。不支持直接覆盖getResource方法ApplicationContext。
Spring Boot提供的重启技术使用两个类加载器。不更改的类(例如,来自第三方jar的类)将加载到基 类加载器中。您正在积极开发的类将加载到重新启动的 类加载器中。重新启动应用程序时,将重新启动的类加载器创建为一个新的类加载器。这种方法意味着应用程序重新启动通常比“冷启动”快得多,因为基本类加载器已经可用并已填充。
如果您发现重新启动对于您的应用程序来说不够快或遇到类加载问题,您可以考虑ZeroTurnaround重新加载JRebel等技术 。这些工作通过在加载类时重写类使它们更适合重新加载。
日志记录评估中的变化
默认情况下,每次应用程序重新启动时,都会记录一个显示条件评估增量的报告。该报告显示了在进行更改(例如添加或删除Bean以及设置配置属性)时对应用程序的自动配置所做的更改。
要禁用报告的日志记录,请设置以下属性:spring.devtools.restart.log-condition-evaluation-delta=false
当某些资源发生更改时,不一定需要触发重新启动。例如,可以就地编辑Thymeleaf模板。默认情况下,在/META-INF/maven、/META-INF/resources、/resources、/static、/public或/template中更改资源不会触发重新启动,但会触发实时重新加载。如果您想自定义这些排除,可以使用spring.devtools.restart.exclude属性。例如,为了只排除/static和/public,您将设置以下属性:spring.devtools.restart.exclude=static/**,public/**
如果要保留这些默认值并添加其他排除项,请改用 spring.devtools.restart.additional-exclude属性。
监听附加路径
当您对不在类路径中的文件进行更改时,您可能希望重新启动或重新加载应用程序。为此,请使用spring.devtools.restart.additional-paths属性配置监视其他路径。您可以使用前面描述的spring.devtools.restart.exclude属性来控制其他路径下的更改是触发完全重新启动还是实时重新加载。
如果您不想使用重新启动功能,可以使用spring.devtools.restart.enabled属性将其禁用。在大多数情况下,您可以在您的application.properties文件中设置此属性(这样做仍会初始化重新启动的类加载器,但它不会监视文件更改)。
如果您需要完全禁用重新启动支持(例如,因为它不能使用特定的库),您需要在调用SpringApplication.run(…)之前将spring.devtools.restart.enabled System属性设置为false,如下面的示例所示:public static void main(String[] args) {
System.setProperty(&spring.devtools.restart.enabled&, &false&);
SpringApplication.run(MyApp.class, args);
使用触发器文件
如果您使用的IDE不断地编译已更改的文件,您可能更希望只在特定的时间触发重新启动。为此,您可以使用“触发器文件”,这是一个特殊的文件,当您希望实际触发重新启动检查时,必须对其进行修改。修改文件只会触发检查,只有在Devtools检测到它必须做一些事情时才会重新启动。触发器文件可以手动更新或使用IDE插件更新。
要使用触发器文件,请将spring.devtools.restart.trigger-file属性设置为触发器文件的路径。
您可能希望将spring.devtools.restart.trigger-file设置为全局设置,以便所有项目都以相同的方式运行。
自定义重启类加载器
如前面在Restart vs Reload部分中所述,使用两个类加载器实现了重启功能。对于大多数应用程序,此方法运行良好。但是,它有时会导致类加载问题。
默认情况下,IDE中的任何打开项目都使用“restart”类加载器加载,并且任何常规.jar文件都使用“base”类加载器加载。如果您处理多模块项目,并且并非每个模块都导入到IDE中,则可能需要自定义内容。为此,您可以创建一个META-INF/spring-devtools.properties文件。
spring-devtools.properties文件可以包含前缀为restart.exclude的属性。include元素是应该被拉高到“restart”的类加载器的项目,以及exclude要素是应该向下推入“base”类加载器的项目。该属性的值是应用于类路径的正则表达式模式,如以下示例所示:restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
只要属性以restart.include或restart.exclude开始。所有属性键必须是唯一的。
从类路径中加载所有META-INF/spring-devtools.properties内容。您可以将文件打包到项目中,也可以打包在项目使用的库中。
已知的限制
重新启动功能不适用于使用标准反序列化的对象ObjectInputStream。如果你需要反序列化的数据,你可能需要使用Spring的ConfigurableObjectInputStream结合 Thread.currentThread().getContextClassLoader()。
不幸的是,几个第三方库反序列化而没有考虑上下文类加载器。如果您发现此类问题,则需要向原始作者请求修复。
LiveReload
spring-boot-devtools模块包括一个嵌入式LiveReload服务器,可用于在更改资源时触发浏览器刷新。LiveReload浏览器扩展程序可从livereload.com免费用于Chrome,Firefox和Safari 。
如果您不想在应用程序运行时启动LiveReload服务器,则可以将spring.devtools.livereload.enabled属性设置为false。
您一次只能运行一个LiveReload服务器。在启动应用程序之前,请确保没有其他LiveReload服务器正在运行。如果从IDE启动多个应用程序,则只有第一个具有LiveReload支持。
您可以通过添加名为.spring-boot-devtools的文件来配置全局devtools设置。你的$HOME文件夹(注意文件名以“.”开头)。任何添加到这个文件的属性都适用于使用devtools的计算机上的所有Spring引导应用程序。例如,要配置重新启动以始终使用触发器文件,您需要添加以下属性:
~/.spring-boot-devtools.propertiesspring.devtools.reload.trigger-file=.reloadtrigger
远程应用程序
Spring Boot开发人员工具不仅限于本地开发。远程运行应用程序时,您还可以使用多个功能。远程支持是选择加入。要启用它,您需要确保devtools包含在重新打包的存档中,如下面的清单所示:&build&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-maven-plugin&/artifactId&
&configuration&
&excludeDevtools&false&/excludeDevtools&
&/configuration&
&/plugins&
然后,您需要设置spring.devtools.remote.secret属性,如以下示例所示:spring.devtools.remote.secret=mysecret
spring-boot-devtools在远程应用程序上启用存在安全风险。您永远不应该在生产部署上启用支持。
远程devtools支持由两部分组成:一个接受连接的服务器端端点和一个在IDE中运行的客户端应用程序。spring.devtools.remote.secret设置属性后,将自动启用服务器组件。必须手动启动客户端组件。
运行远程客户端应用程序
远程客户端应用程序设计为从您的IDE中运行。您需要运行org.springframework.boot.devtools.RemoteSpringApplication,其类路径与连接到的远程项目相同。应用程序的唯一必需参数是它连接到的远程URL。
例如,如果您使用的是Eclipse或STS,并且您有一个名为my-app已部署到Cloud Foundry的项目,那么您将执行以下操作:
选择Run Configurations…从Run菜单。创建一个新的Java Application“启动配置”。浏览my-app项目。用org.springframework.boot.devtools.RemoteSpringApplication作主类。添加https://myapp.cfapps.io到Program arguments(或任何远程URL)。
正在运行的远程客户端可能类似于以下内容:
/\\ / ___'_ __ _ _(_)_ __
( ( )\___ | '_ | '_| | '_ \/ _` |
| _ \___ _ __
___| |_ ___ \ \ \ \
___)| |_)| | | | | || (_| []::::::[]
_/ -_) ) ) ) )
|____| .__|_| |_|_| |_\__, |
|_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: 2.0.4.RELEASE
18:25:06.632
INFO 14938 --- [
main] o.s.b.devtools.RemoteSpringApplication
: Starting RemoteSpringApplication on pwmbp with PID 14938 (/Users/pwebb/projects/spring-boot/code/spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code/spring-boot-samples/spring-boot-sample-devtools)
18:25:06.671
INFO 14938 --- [
main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2a17b7b6: startup date [Wed Jun 10 18:25:06 PDT 2015]; root of context hierarchy
18:25:07.043
WARN 14938 --- [
main] o.s.b.d.r.c.RemoteClientConfiguration
: The connection to http://localhost:8080 is insecure. You should use a URL starting with 'https://'.
18:25:07.074
INFO 14938 --- [
main] o.s.b.d.a.OptionalLiveReloadServer
: LiveReload server is running on port 35729
18:25:07.130
INFO 14938 --- [
main] o.s.b.devtools.RemoteSpringApplication
: Started RemoteSpringApplication in 0.74 seconds (JVM running for 1.105)
因为远程客户端使用与实际应用程序相同的类路径,所以可以直接读取应用程序属性。这就是spring.devtools.remote.secret属性的读取方式,并将其传递给服务器进行身份验证。
使用https://作为连接协议总是明智的,这样就可以加密传输并不能截获密码。
如果需要使用代理访问远程应用程序,请配置spring.devtools.remote.proxy.host和spring.devtools.remote.proxy.port属性。
远程客户端以与本地重启相同的方式监视应用程序类路径的更改。将任何更新的资源推到远程应用程序,并(如果需要)触发重新启动。如果您对使用本地没有的云服务的特性进行迭代,这将非常有用。通常,远程更新和重新启动要比完整的重新构建和部署周期快得多。
只有在远程客户端运行时才对文件进行监视。如果在启动远程客户端之前更改文件,则不会将其推到远程服务器。
Spring Boot包含一组开发工具,可以使应用程序开发体验更加愉快。spring-boot-devtools模块可以包含在任何项目中,以提供额外的开发功能。要包含devtools支持,请将模块依赖项添加到您的构建配置中,如以下Maven和Gradle列表所示:
Maven&dependencies&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-devtools&/artifactId&
&optional&true&/optional&
&/dependency&
&/dependencies&
Gradledependencies {
compile(&org.springframework.boot:spring-boot-devtools&)
在运行完全打包的应用程序时,会自动禁用开发工具。如果您的应用程序是从java -jar启动的,或者是从一个特殊的类加载程序启动的,那么它被认为是一个“(production application)生产应用程序”。将依赖项标记为Maven中的可选项或在Gradle中只使用compileOnly是防止devtools临时应用到使用项目的其他模块的最佳实践。
重新打包默认情况下不包含devtools。如果您想使用某个远程devtools特性,您需要禁用excludeDevtools build属性。Maven和Gradle插件都支持这个属性。
属性默认值
Spring Boot支持几个库使用缓存来提高性能。例如,缓存已编译的模板以避免重复解析模板文件。此外,Spring MVC可以在提供静态资源时为响应添加HTTP缓存头。
虽然缓存在生产中非常有用,但在开发过程中可能会适得其反,从而使您无法看到刚刚在应用程序中进行的更改。因此,spring-boot-devtools默认禁用缓存选项。
缓存选项通常由application.properties文件中配置。例如,Thymeleaf提供该spring.thymeleaf.cache配置。spring-boot-devtools模块不需要手动设置这些属性,而是自动应用合理的开发时配置
有关devtools应用的属性的完整列表,请参阅 DevToolsPropertyDefaultsPostProcessor。
使用spring-boot-devtools的应用程序在类路径更改时自动重新启动。在IDE中工作时,这可能是一个有用的特性,因为它为代码更改提供了一个非常快速的反馈循环。默认情况下,指向文件夹的类路径中的任何条目都将受到监视,以查看是否有更改。注意,某些资源(如静态资产和视图模板)不需要重新启动应用程序。
由于DevTools监视类路径资源,因此触发重新启动的唯一方法是更新类路径。导致更新类路径的方式取决于您使用的IDE。在Eclipse中,保存修改后的文件会导致更新类路径并触发重新启动。在IntelliJ IDEA中,构建项目(Build -& Build Project)具有相同的效果。
只要启用了forking,您就可以使用支持的构建插件(Maven和Gradle)来启动应用程序,因为DevTools需要一个独立的应用程序类加载器才能正常运行。默认情况下,Gradle和Maven会在类路径上检测DevTools。
与LiveReload一起使用时,自动重启非常有效。 有关详细信息,请参阅LiveReload部分。如果使用JRebel,则禁用自动重新启动以支持动态类重新加载。其他devtools功能(例如LiveReload和属性覆盖)仍然可以使用。
DevTools依赖于应用程序上下文的关机挂钩在重新启动时关闭它。如果您已经禁用了关闭钩子(SpringApplication.setRegisterShutdownHook(false)),那么它将无法正常工作。
当决定是否在类路径中的条目应该触发重新启动时,DevTools自动忽略命名的项目spring-boot, spring-boot-devtools,spring-boot-autoconfigure,spring-boot-actuator,和spring-boot-starter。
DevTools需要自定义ResourceLoader使用的ApplicationContext。如果您的应用程序已经提供了一个,它将被打包。不支持直接覆盖getResource方法ApplicationContext。
Spring Boot提供的重启技术使用两个类加载器。不更改的类(例如,来自第三方jar的类)将加载到基 类加载器中。您正在积极开发的类将加载到重新启动的 类加载器中。重新启动应用程序时,将重新启动的类加载器创建为一个新的类加载器。这种方法意味着应用程序重新启动通常比“冷启动”快得多,因为基本类加载器已经可用并已填充。
如果您发现重新启动对于您的应用程序来说不够快或遇到类加载问题,您可以考虑ZeroTurnaround重新加载JRebel等技术 。这些工作通过在加载类时重写类使它们更适合重新加载。
日志记录评估中的变化
默认情况下,每次应用程序重新启动时,都会记录一个显示条件评估增量的报告。该报告显示了在进行更改(例如添加或删除Bean以及设置配置属性)时对应用程序的自动配置所做的更改。
要禁用报告的日志记录,请设置以下属性:spring.devtools.restart.log-condition-evaluation-delta=false
当某些资源发生更改时,不一定需要触发重新启动。例如,可以就地编辑Thymeleaf模板。默认情况下,在/META-INF/maven、/META-INF/resources、/resources、/static、/public或/template中更改资源不会触发重新启动,但会触发实时重新加载。如果您想自定义这些排除,可以使用spring.devtools.restart.exclude属性。例如,为了只排除/static和/public,您将设置以下属性:spring.devtools.restart.exclude=static/**,public/**
如果要保留这些默认值并添加其他排除项,请改用 spring.devtools.restart.additional-exclude属性。
监听附加路径
当您对不在类路径中的文件进行更改时,您可能希望重新启动或重新加载应用程序。为此,请使用spring.devtools.restart.additional-paths属性配置监视其他路径。您可以使用前面描述的spring.devtools.restart.exclude属性来控制其他路径下的更改是触发完全重新启动还是实时重新加载。
如果您不想使用重新启动功能,可以使用spring.devtools.restart.enabled属性将其禁用。在大多数情况下,您可以在您的application.properties文件中设置此属性(这样做仍会初始化重新启动的类加载器,但它不会监视文件更改)。
如果您需要完全禁用重新启动支持(例如,因为它不能使用特定的库),您需要在调用SpringApplication.run(…)之前将spring.devtools.restart.enabled System属性设置为false,如下面的示例所示:public static void main(String[] args) {
System.setProperty(&spring.devtools.restart.enabled&, &false&);
SpringApplication.run(MyApp.class, args);
使用触发器文件
如果您使用的IDE不断地编译已更改的文件,您可能更希望只在特定的时间触发重新启动。为此,您可以使用“触发器文件”,这是一个特殊的文件,当您希望实际触发重新启动检查时,必须对其进行修改。修改文件只会触发检查,只有在Devtools检测到它必须做一些事情时才会重新启动。触发器文件可以手动更新或使用IDE插件更新。
要使用触发器文件,请将spring.devtools.restart.trigger-file属性设置为触发器文件的路径。
您可能希望将spring.devtools.restart.trigger-file设置为全局设置,以便所有项目都以相同的方式运行。
自定义重启类加载器
如前面在Restart vs Reload部分中所述,使用两个类加载器实现了重启功能。对于大多数应用程序,此方法运行良好。但是,它有时会导致类加载问题。
默认情况下,IDE中的任何打开项目都使用“restart”类加载器加载,并且任何常规.jar文件都使用“base”类加载器加载。如果您处理多模块项目,并且并非每个模块都导入到IDE中,则可能需要自定义内容。为此,您可以创建一个META-INF/spring-devtools.properties文件。
spring-devtools.properties文件可以包含前缀为restart.exclude的属性。include元素是应该被拉高到“restart”的类加载器的项目,以及exclude要素是应该向下推入“base”类加载器的项目。该属性的值是应用于类路径的正则表达式模式,如以下示例所示:restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
只要属性以restart.include或restart.exclude开始。所有属性键必须是唯一的。
从类路径中加载所有META-INF/spring-devtools.properties内容。您可以将文件打包到项目中,也可以打包在项目使用的库中。
已知的限制
重新启动功能不适用于使用标准反序列化的对象ObjectInputStream。如果你需要反序列化的数据,你可能需要使用Spring的ConfigurableObjectInputStream结合 Thread.currentThread().getContextClassLoader()。
不幸的是,几个第三方库反序列化而没有考虑上下文类加载器。如果您发现此类问题,则需要向原始作者请求修复。
LiveReload
spring-boot-devtools模块包括一个嵌入式LiveReload服务器,可用于在更改资源时触发浏览器刷新。LiveReload浏览器扩展程序可从免费用于Chrome,Firefox和Safari 。
如果您不想在应用程序运行时启动LiveReload服务器,则可以将spring.devtools.livereload.enabled属性设置为false。
您一次只能运行一个LiveReload服务器。在启动应用程序之前,请确保没有其他LiveReload服务器正在运行。如果从IDE启动多个应用程序,则只有第一个具有LiveReload支持。
您可以通过添加名为.spring-boot-devtools的文件来配置全局devtools设置。你的$HOME文件夹(注意文件名以“.”开头)。任何添加到这个文件的属性都适用于使用devtools的计算机上的所有Spring引导应用程序。例如,要配置重新启动以始终使用触发器文件,您需要添加以下属性:
~/.spring-boot-devtools.propertiesspring.devtools.reload.trigger-file=.reloadtrigger
远程应用程序
Spring Boot开发人员工具不仅限于本地开发。远程运行应用程序时,您还可以使用多个功能。远程支持是选择加入。要启用它,您需要确保devtools包含在重新打包的存档中,如下面的清单所示:&build&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-maven-plugin&/artifactId&
&configuration&
&excludeDevtools&false&/excludeDevtools&
&/configuration&
&/plugins&
然后,您需要设置spring.devtools.remote.secret属性,如以下示例所示:spring.devtools.remote.secret=mysecret
spring-boot-devtools在远程应用程序上启用存在安全风险。您永远不应该在生产部署上启用支持。
远程devtools支持由两部分组成:一个接受连接的服务器端端点和一个在IDE中运行的客户端应用程序。spring.devtools.remote.secret设置属性后,将自动启用服务器组件。必须手动启动客户端组件。
运行远程客户端应用程序
远程客户端应用程序设计为从您的IDE中运行。您需要运行org.springframework.boot.devtools.RemoteSpringApplication,其类路径与连接到的远程项目相同。应用程序的唯一必需参数是它连接到的远程URL。
例如,如果您使用的是Eclipse或STS,并且您有一个名为my-app已部署到Cloud Foundry的项目,那么您将执行以下操作:
选择Run Configurations…从Run菜单。创建一个新的Java Application“启动配置”。浏览my-app项目。用org.springframework.boot.devtools.RemoteSpringApplication作主类。添加 arguments(或任何远程URL)。
正在运行的远程客户端可能类似于以下内容:
/\\ / ___'_ __ _ _(_)_ __
( ( )\___ | '_ | '_| | '_ \/ _` |
| _ \___ _ __
___| |_ ___ \ \ \ \
___)| |_)| | | | | || (_| []::::::[]
_/ -_) ) ) ) )
|____| .__|_| |_|_| |_\__, |
|_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: 2.0.4.RELEASE
18:25:06.632
INFO 14938 --- [
main] o.s.b.devtools.RemoteSpringApplication
: Starting RemoteSpringApplication on pwmbp with PID 14938 (/Users/pwebb/projects/spring-boot/code/spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code/spring-boot-samples/spring-boot-sample-devtools)
18:25:06.671
INFO 14938 --- [
main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2a17b7b6: startup date [Wed Jun 10 18:25:06 PDT 2015]; root of context hierarchy
18:25:07.043
WARN 14938 --- [
main] o.s.b.d.r.c.RemoteClientConfiguration
: The connection to http://localhost:8080 is insecure. You should use a URL starting with 'https://'.
18:25:07.074
INFO 14938 --- [
main] o.s.b.d.a.OptionalLiveReloadServer
: LiveReload server is running on port 35729
18:25:07.130
INFO 14938 --- [
main] o.s.b.devtools.RemoteSpringApplication
: Started RemoteSpringApplication in 0.74 seconds (JVM running for 1.105)
因为远程客户端使用与实际应用程序相同的类路径,所以可以直接读取应用程序属性。这就是spring.devtools.remote.secret属性的读取方式,并将其传递给服务器进行身份验证。
使用https://作为连接协议总是明智的,这样就可以加密传输并不能截获密码。
如果需要使用代理访问远程应用程序,请配置spring.devtools.remote.proxy.host和spring.devtools.remote.proxy.port属性。
远程客户端以与本地重启相同的方式监视应用程序类路径的更改。将任何更新的资源推到远程应用程序,并(如果需要)触发重新启动。如果您对使用本地没有的云服务的特性进行迭代,这将非常有用。通常,远程更新和重新启动要比完整的重新构建和部署周期快得多。
只有在远程客户端运行时才对文件进行监视。如果在启动远程客户端之前更改文件,则不会将其推到远程服务器。
发表了文章 o 0 个评论 o 14 次浏览 o
o 来自相关话题
将应用程序打包为jar并使用嵌入式HTTP服务器的最大优势之一是,您可以像运行任何其他服务器一样运行应用程序。调试Spring Boot应用程序也很容易。您不需要任何特殊的IDE插件或扩展。
本节只讨论基于jar的打包。如果您选择将应用程序打包为war文件,您应该参考服务器和IDE文档。
您可以从IDE运行Spring Boot应用程序作为简单的Java应用程序。但是,您首先需要导入项目。导入步骤因IDE和构建系统而异。大多数IDE可以直接导入Maven项目。例如,Eclipse用户可以从菜单中选择File按钮Import… → Existing Maven Projects
如果无法将项目直接导入IDE,则可以使用构建插件生成IDE元数据。Maven包含Eclipse和IDEA的插件 。Gradle提供各种IDE的插件 。
如果您不小心运行了两次Web应用程序,则会看到“Port already in use”错误。STS用户可以使用Relaunch按钮而不是Run按钮来确保关闭任何现有实例。
作为打包应用程序运行
如果使用Spring Boot Maven或Gradle插件创建可执行jar,则可以使用运行应用程序java -jar,如以下示例所示:$ java -jar target/myapplication-0.0.1-SNAPSHOT.jar
也可以运行启用了远程调试支持的打包应用程序。这样做可以将调试器附加到打包的应用程序,如以下示例所示:$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
-jar target/myapplication-0.0.1-SNAPSHOT.jar
使用Maven插件
Spring Boot Maven插件包含一个run可用于快速编译和运行应用程序的命令。应用程序以分解形式运行,就像在IDE中一样。以下示例显示了运行Spring Boot应用程序的典型Maven命令:$ mvn spring-boot:run
您可能还想使用MAVEN_OPTS操作系统环境变量,如以下示例所示:$ export MAVEN_OPTS=-Xmx1024m
使用Gradle插件
Spring Boot Gradle插件还包含一个bootRun可用于以爆炸形式运行应用程序的任务。每当您应用org.springframework.boot和java插件时都会添加bootRun任务,如以下示例所示:$ gradle bootRun
您可能还想使用JAVA_OPTS操作系统环境变量,如以下示例所示:$ export JAVA_OP

我要回帖

更多关于 触发器是不是组合逻辑电路 的文章

 

随机推荐