我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Spring Boot学习记3

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Spring Boot学习记3

  1. 点睛

    在我们实际开发的时候,经常会遇到在Bean在使用之前或者止呕做一些必要的操作,Spring对Bean的生命周期的操作提供了支持。在使用Java配置和注解配置下提供如下两种方式:

  2. Java配置方式:使用@Bean的initMethod和destroyMethod(相当于XML配置init-method和destory-method)。

  3. 注解方式:利用JSR-250的@PostConstruct和@PreDestroy。

  4. 示例

  5. 被注入Bean

package hightlight_spirng4.ch2.prepost;

 

 

public class BeanWayService {

        public BeanWayService() {

                System.out.println("初始化構造函数-BeanWayService");

        }

        public void init() {

                System.out.println("@Bean-init-Method");

               

        }

        public void destroy() {

                System.out.println("@Bean-destory-Method");

        }

 

}

 

package hightlight_spirng4.ch2.prepost;

 

import javax.annotation.PostConstruct;

import javax.annotation.PreDestroy;

 

public class JSR250WayService {

        public JSR250WayService() {

                System.out.println("初始化構造函数-JSR250WayService");

        }

        @PostConstruct //1 在构造函数执行完之后执行

        public void init() {

                System.out.println("JSR250-init-Method");

        }

        @PreDestroy //2 在Bean销毁之前执行

        public void destroy() {

                System.out.println("JSR250-destory-Method");

        }

 

}

 

 

  1. 配置类

package hightlight_spirng4.ch2.prepost;

 

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

 

@Configuration

@ComponentScan("hightlight_spirng4.ch2.prepost")

public class PrePostConfig {

        // initMethod 和destroyMethod 指定BeanWayService 类的init 和destroy

    // 方法在构造之后、Bean 销毁之前执行。

        @Bean(initMethod="init",destroyMethod="destroy")

        public BeanWayService beanWayService() {

                return new BeanWayService();

        }

       

        @Bean

        public JSR250WayService   jsr250WayService() {

                return new JSR250WayService();

        }

}

 

 

  1. 运行

package hightlight_spirng4.ch2.prepost;

 

import   org.springframework.context.annotation.AnnotationConfigApplicationContext;

 

public class Main {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext context =

                new   AnnotationConfigApplicationContext(PrePostConfig.class);

 

        BeanWayService beanWayService = context.getBean(BeanWayService.class);

        JSR250WayService JSR250WayService = context.getBean(JSR250WayService.class);

 

 

        context.close();

    }

}

结果

r6.png                                           

  1. 点睛

Profile为在不同环境下使用不同的配置提供了支持(开发环境下的配置和生产环境下的配置肯定是不同的,例如数据库配置)

  1. 通过设定Environment的ActiveProfile来设定当前context需要使用的配置环境。在开发中使用@Profile注解类或者方法,达到在不同情况下选择实例化不同的Bean。

  2. 通过设定jvm的spring.profiles.active参数来设置配置环境。

  3. Web项目设置在Servlet的context parameter中。

  4. 示例

package hightlight_spirng4.ch2.profile;

 

public class DemoBean {

       

        public DemoBean(String content) {

                super();

                this.content=content;

        }

       

        private String content;

       

        public String getContent() {

                return content;

        }

        public void setContent(String content) {

                this.content = content;

        }

       

}

 

package hightlight_spirng4.ch2.profile;

 

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Profile;

@Configuration

public class ProfileConfig {

        @Bean

        @Profile("dev") //1

        public DemoBean deveDemoBean() {

                return new DemoBean("from development profile");

        }

       

        @Bean

        @Profile("prod") //2

        public DemoBean proDemoBean() {

                return new DemoBean("from production profile");

        }

}

 

 

  1. 结果

r5.png

  1. 点睛

    Spring的事件(Application Event)为Bean与Bean之间的消息通信提供了支持。当一个Bean处理完一个任务之后,希望另一个Bean知道并能做相应的处理,这时外面见需要让另外一个Bean监听当前Bean所发送的事件。

    Spring的事件需要遵循如下流程:

  2. 自定义事件,继承ApplicationEvent。

  3. 定义事件监听器,实现ApplicationListener。

  4. 使用容器发布事件。

  5. 示例

package hightlight_spirng4.ch2.event;

 

import org.springframework.context.ApplicationEvent;

 

public class DemoEvent extends ApplicationEvent {

 

       

        private static final long serialVersionUID = 1L;

       

        private String msg;

       

       

 

        public DemoEvent(Object source,String msg) {

                super(source);

                this.msg=msg;

        }

 

 

 

        public String getMsg() {

                return msg;

        }

 

 

 

        public void setMsg(String msg) {

                this.msg = msg;

        }

       

       

       

 

}

 

package hightlight_spirng4.ch2.event;

 

import org.springframework.context.ApplicationListener;

import org.springframework.stereotype.Component;

 

@Component

public class DemoListener implements   ApplicationListener<DemoEvent> { //1

 

        @Override

        public void onApplicationEvent(DemoEvent event) { //2

                String msg=event.getMsg();

                System.out.println("我(bean-demoListener)接受到了bean-demoPublisher发布的消息:" + msg);

                System.out.println("发生事件的对象是:" + event.getSource());

 

        }

 

}

 

package hightlight_spirng4.ch2.event;

 

import   org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.ApplicationContext;

import org.springframework.stereotype.Component;

 

@Component

public class DemoPublisher {

        @Autowired //1

        ApplicationContext context;

       

        public void publish(String msg) {

                context.publishEvent(new DemoEvent(this, msg)); //2

        }

}

 

package hightlight_spirng4.ch2.event;

 

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

 

@Configuration

@ComponentScan("hightlight_spirng4.ch2.event")

public class EventConfig {

 

}

 

package hightlight_spirng4.ch2.event;

 

import   org.springframework.context.annotation.AnnotationConfigApplicationContext;

 

public class Main {

 

        public static void main(String[] args) {

                AnnotationConfigApplicationContext   context = new AnnotationConfigApplicationContext(EventConfig.class);

                DemoPublisher publisher = context.getBean(DemoPublisher.class);

                publisher.publish("Hello application event");

                context.close();

 

        }

 

}

 

  1. 结果

r4.png

  1. 点睛

    Spring的依赖注入最大的亮点就是所有的Bean对Spring容器的存在是没有意识的。即你可以将你的容器替换成别的容器,如Google Guice,只是Bean之间的耦合度很低。

    但是在实际项目中,你不可避免的要用到Spring容器本身的功能资源,这时你的Bean必须要意识到Spring容器的存在,才能调用Spring所提供的资源,着就是所谓的Spring Aware。其实Spring Aware本来就是Spring设计用来框架内部使用的,若使用了Spring Aware,你的Bean将会和Spring框架耦合。

    Spring提供的Aware接口如下所示:

BeanNameAware

获得到容器中Bean名称

BeanFactoryAware

获得当前Bean   Factory,这样可以调用容器的服务

ApplicationContextAware*

当前ApplicationContext,这样可以调用容器的服务

MessageSourceAware

获得messagesource,这样可以获得文本信息

ApplicationEventPublisherAware

应用事件发布器,可以发布事件

ResourceLoaderAware

获得资源加载器,可以获得外部资源文件

Spring Aware的目的是为了让Bean获得Spring容器的服务。因为ApplicationContext接口集成了MessageSource接口、ApplicationEventPublisher接口和ResourceLoader接口,所以Bean继承ApplicationContextAware可以获得Spring容器的所有服务,但原则上我们还是用到什么接口,就实现什么接口。

  1. 示例

  2. 准备。新建test.txt,内容随意,给下面的外部资源加载使用。

  3. Spring Aware演示Bean。

package hightlight_spirng4.ch3.aware;

 

import org.apache.commons.io.IOUtils;

import org.springframework.beans.factory.BeanNameAware;

import org.springframework.context.ResourceLoaderAware;

import org.springframework.core.io.Resource;

import org.springframework.core.io.ResourceLoader;

import org.springframework.stereotype.Service;

@Service

public class BeanService implements BeanNameAware,   ResourceLoaderAware {//1

        private String BeanName;

        private ResourceLoader resourceLoader;

 

        @Override

        public void setResourceLoader(ResourceLoader resourceLoader) {//2

                this.resourceLoader=resourceLoader;

 

        }

 

        @Override

        public void setBeanName(String name) {//3

                this.BeanName=name;

        }

       

        public void outputResult() {

                System.out.println("BeanName is "+BeanName);

                Resource resource = resourceLoader.getResource("classpath:hightlight_spirng4/ch3/aware/test.txt");

                try {

                        System.out.println("resource info :"+IOUtils.toString(resource.getInputStream(), "utf-8"));

                } catch (Exception e) {

                        e.printStackTrace();

                }

        }

 

}

 

package hightlight_spirng4.ch3.aware;

 

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

 

@Configuration

@ComponentScan("hightlight_spirng4.ch3.aware")

public class AwareConfig {

 

}

 

package hightlight_spirng4.ch3.aware;

 

import   org.springframework.context.annotation.AnnotationConfigApplicationContext;

 

public class Main {

 

        public static void main(String[] args) {

                AnnotationConfigApplicationContext   context = new AnnotationConfigApplicationContext(AwareConfig.class);

                BeanService bean=context.getBean(BeanService.class);

                bean.outputResult();

                context.close();

 

        }

 

}

 

 

  1. 结果

r3.png

  1. 点睛

    Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用RhreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor。而实际开发中人物一般式非阻碍的,即异步的,所以我们要在配置类中通过@EnableAsync开始起对一部人物的支持,并通过在实际执行的Bean的方法中使用@Async注解来声明其是一个异步任务。

  2. 示例

package hightlight_spirng4.ch3.taskexecutor;

 

import java.util.concurrent.Executor;

 

import   org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import   org.springframework.scheduling.annotation.AsyncConfigurer;

import org.springframework.scheduling.annotation.EnableAsync;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration

@ComponentScan("hightlight_spirng4.ch3.taskexecutor")

@EnableAsync //1 开启异步任务支持

//2配置类实现AsyncConfigurer 接口并重写getAsyncExecutor 方法,并返回一个ThreadPoolTaskExecutor ,这样我们就获得了一个基于线程池TaskExecutor。

public class TaskExecutorConfig implements AsyncConfigurer {

 

 

        @Override

        public Executor getAsyncExecutor() {

                ThreadPoolTaskExecutor taskExecutor = new   ThreadPoolTaskExecutor();

                taskExecutor.setCorePoolSize(5);

                taskExecutor.setMaxPoolSize(10);

                taskExecutor.setQueueCapacity(25);

                taskExecutor.initialize();

                return taskExecutor;

        }

 

        @Override

        public AsyncUncaughtExceptionHandler   getAsyncUncaughtExceptionHandler() {

                // TODO Auto-generated method stub

                return null;

        }

 

       

 

}

 

package hightlight_spirng4.ch3.taskexecutor;

 

import org.springframework.scheduling.annotation.Async;

import org.springframework.stereotype.Service;

 

@Service

public class AsyncTaskService {

        @Async

        public void executeAsyncTask(Integer i) {

                System.out.println("Async task: "+i);

        }

        @Async

        public void executeAsyncTaskPlus(Integer i) {

                System.out.println("Async task i+1: "+(i+1));

        }

}

 

package hightlight_spirng4.ch3.taskexecutor;

 

import   org.springframework.context.annotation.AnnotationConfigApplicationContext;

 

public class Main {

        public static void main(String[] args) {

                AnnotationConfigApplicationContext   context = new AnnotationConfigApplicationContext(TaskExecutorConfig.class);

                AsyncTaskService bean=context.getBean(AsyncTaskService.class);

                for(int i=0;i<10;i++) {

                        bean.executeAsyncTask(i);

                        bean.executeAsyncTaskPlus(i);

                }

                context.close();

        }

}

 

结果并发执行并不是顺序的

r2.png

  1. 点睛

    从Spring3.1开始,计划任务在Spring中的实现变得异常的简单。首先通过在配置类注解@EnableScheduling来开启对计划任务的支持,然后在执行计划任务的方法上注解@Scheduled,声明这是一个计划任务。

    Sring通过@Scheduled支持多种类型的任务计划,包含cron、fixDelay、fixRate等。

  2. 示例

package hightlight_spirng4.ch3.taskscheduler;

 

import java.text.SimpleDateFormat;

import java.util.Date;

 

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Service;

 

@Service

public class ScheduledTaskService {

        private static final SimpleDateFormat dateformat = new SimpleDateFormat("HH:mm:ss");

       

        //声明该方法是计划任务,使用fixedRate属性每隔固定时间执行

        @Scheduled(fixedRate=5000)

        public void reportCurrentTime() {

                System.out.println("每隔5秒执行一次:"+dateformat.format(new Date()));

        }

        //可按照指定时间执行,每天11点28分执行。cron是UNIX和类UNIX系统下的定时任务

        @Scheduled(cron="0 28 11 ? * *")

        public void fixTimeExecut() {

                System.out.println("指定时间执行:"+dateformat.format(new Date()));

        }

                       

 

}

 

package hightlight_spirng4.ch3.taskscheduler;

 

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import   org.springframework.scheduling.annotation.EnableScheduling;

 

@Configuration

@ComponentScan("hightlight_spirng4.ch3.taskscheduler")

@EnableScheduling  //开启对计划任务的支持

public class TaskScheduledConfig {

 

}

package hightlight_spirng4.ch3.taskscheduler;

 

import   org.springframework.context.annotation.AnnotationConfigApplicationContext;

 

public class Main {

        public    static void main(String[] args) {

                AnnotationConfigApplicationContext   context = new AnnotationConfigApplicationContext(TaskScheduledConfig.class);

                ScheduledTaskService bean=context.getBean(ScheduledTaskService.class);

                bean.reportCurrentTime();

                bean.fixTimeExecut();

                context.close();

        }

}

 

 

  1. 结果

r.png

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Spring Boot学习记3

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Spring Boot学习记3

点睛在我们实际开发的时候,经常会遇到在Bean在使用之前或者止呕做一些必要的操作,Spring对Bean的生命周期的操作提供了支持。在使用Java配置和注解配置下提供如下两种方式:Java配置方式:使用@Bean的initMethod和de
2023-01-31

Spring Security 3 学习

学习SpringSecurity3之前,我在网上找了很多关于SpringSecurity3的相关博客,写得都很好,刚开始我都看不懂,后来在ITEYE里面看到有人把一本国外的书翻译过来了,很不错,免费下载的。所以学习SpringSecurit
2023-01-31

学习笔记(3)

1.* 匹配零个或多个字符(通配符中)2.ls 的-d选项不仅仅可以显示指定目录的信息,还可以用来表示不递归子文件夹。  # ls -dl /etc 显示/etc目录的信息  # ls -d /etc/* 显示/etc下面的文件和文件夹,并
2023-01-31

学习笔记3

一文件查找和压缩1文件查找locate 搜索依赖于数据库,非实时搜索,搜索新建文件需手动更新,适于搜索稳定不频繁修改文件 find 实时搜索,精确搜索,默认当前目录递归搜索 find用法 -maxdepth l
2023-01-31

OSPF 学习笔记3

ospf特殊区域减少LSA洪泛,达到优化路由表的目的sub区域特点1、过滤了LSA4/52、通过ABR的LSA3学习到一条到达域外的缺省路由(O*IA)3、区域内所有的路由器都得设置为stub路由器4、stub区域内不能有ASBR5、stu
2023-01-31

CCNP学习笔记(3)

一、RIPv2:Routing Information Protocol 路由信息协议 1.特性: ①属于“距离矢量”路由协议 ②定期发送路由更新(30S一次,路由表中所有路由) ③依据“跳数”衡量路径好坏  //跳数(hop):route
2023-01-31

python学习笔记(3)

在大概了解了程序之后,我也买了本python书学习一下,因为现在新版的python3.4.0已经不再兼容2.x.x的内容,书虽然很新,但是有些例子还是用的过去的。1.比如在3.0中print 42不能再产生输出了,要改成print(42)>
2023-01-31

PowerShell 学习笔记(3)

获取对象的过程中,最好先筛选出对象,再进行操作。(即筛选在排序左边)不区分大小写get-process | where {$_.handles –ge 1000}使用where获取所有对象,用对象执行大括号里的代码,如果结果为rue,则返回
2023-01-31

PHP 学习笔记 (3)

昨天笔记2说道了PHP的标记以及短标记,今天记录下如何吧PHP从HTML分离手册参考:http://www.php.net/manual/zh/language.basic-syntax.phpmode.phpPHP手册告诉我们,PHP凡是
2023-01-31

CCNA学习日记3

下面把今天学到的重点总结一下,如果有什么错误,欢迎大家纠正! 1. 路由器密码配置n控制台密码Router(config)#line console 0Router(config-line)#loginRouter(config-line)
2023-01-31

GEF学习笔记3

八、创建嵌套的视图 前面的步骤,创建了公司视图,下面再创建一个国家视图用来容纳公司视图。这就需要按前面的方法把MVC都重新创建一遍。ModelView(Figure)Control(EditPart)注意重写红框中标识的getModelCh
2023-01-31

cisco学习笔记(3)

1. 交换机支持的命令:交换机基本状态: switch: ;ROM状态, 路由器是rommon>hostname> ;用户模式hostname# ;特权模式hostname(config)# ;全局配置模式hostname(config-i
2023-01-31

perl学习笔记(3)

条件结构:if(...){      ...;}elsif(...){      ...;}else{      ...;}数值关系运算符 ==,>,<,>=,<=,!=字符串关系     eq,gt,lt,ge,le,ne逻辑运算 与&&
2023-01-31

shell 学习笔记3

####shell结构#!指定执行脚本的shell#注释行命令和控制结构 第一步:创建一个包含命令和控制结构的文件 第二步:修改这个文件的权限使它可以执行,chmod u+x 第三步:执行./example(或sh example,使用此方
2023-01-31

shell学习笔记(3)

一、if基础1、单分支1.1 语法if语句语法 单分支结构语法: if [条件]; then 指令 fi 或 if [条件] then 指令 fi1.2
2023-01-31

solaris学习笔记3:mount

mount学习 1.文件系统基本概念,UFS,ZFS,VxFS,WAFL 2./etc/vfstab 预定义挂载文件系统;   /etc/mnttab 已挂载文件系统 3.man mount   man mount_ufs   man mo
2023-01-31

MySQL学习笔记(3):SQL

本文章更新于2020-06-14,使用MySQL 5.7,操作系统为Deepin 15.9。目录DDL语句创建数据库删除数据库修改数据库创建表删除表修改表创建索引删除索引创建视图修改视图删除视图存储过程和函数创建事件修改事件删除事件创建触发器删除触发器DML语
MySQL学习笔记(3):SQL
2022-04-25

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录