技术标签: spring java Spring和SpringMVC框架案例 JavaEE
上篇文章我们简单介绍了Spring的基本配置,算是一个简单的入门,这篇文章我们再一起来看看Spring在使用的过程中一些其他的常见配置。
Spring中的Scope注解主要是为了解决Bean的实例问题,就是Bean在不同的场合下到底该有几个实例,是单例模式还是其他模式?一般来说,Spring的Scope有如下几种:
1.Singleton:表示该Bean是单例模式,在Spring容器中共享一个Bean的实例
2.Prototype:每次调用都会新创建一个Bean的实例
3.Request:这个是使用在Web中,给每一个http request新建一个Bean实例
4.Session:这个同样是使用在Web中,表示给每一个http session新建一个Bean实例
OK,接下来通过一个简单的案例来看看@Scope注解要怎么使用:
1.编写一个Bean
Component
@Scope("singleton")
public class ScopeTest {
}
小伙伴们注意,这里我使用了@Scope("singleton")
注解,这个注解表示该类是一个单例模式,如果想使用prototype模式,将singleton
改为prototype
即可。
2.配置类
@Configuration
@ComponentScan("org.sang")
public class MyConfig {
}
这个配置类很简单,没什么好说的,有疑问请查看上篇博文。
3.使用
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
ScopeTest bean1 = context.getBean(ScopeTest.class);
ScopeTest bean2 = context.getBean(ScopeTest.class);
System.out.println(bean1.equals(bean2));
context.close();
}
}
这里的我们直接获取两个ScopeTest类的实例,然后比较这两个是否是同一个就可以知道@Scope注解是否生效,运行结果如下:
OK,接下来我们把第一步创建的类的@Scope注解修改一下,改成下面的样子:
@Component
@Scope("prototype")
public class ScopeTest {
}
这个时候再运行,结果如下:
本案例下载地址:
Spring 中的EL 表达式有点类似于JSP中的EL表达式,它支持在xml文件和注解中使用表达式。另一方面,JavaEE开发中我们可能经常要注入不同类型的文件,这些文件在注入成功之后我们要通过EL来提取其中的值,OK,那我们来看一个简单的实例。
1.添加commons-io工具类,简化file操作
因为本案例后面会涉及到一点IO操作,使用这个工具类可以帮助我们简化操作
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
2.添加t.txt文件、t.properties文件
添加两个文件来演示文件的注入,我使用IntelliJ IDEA来做开发的,我们这两个文件放在resources文件夹中,如下:
t.txt文件中的内容随意,t.properties文件中的内容也随意,以我的这两个文件为例:
3.编写需要被注入的Bean
@Service
public class DemoService1 {
//注入普通字符串
@Value("老王")
private String author;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
这个很简单,不多说。
4.编写配置类
@Configuration
@ComponentScan("org.sang")
@PropertySource(value = "t.properties",encoding = "UTF-8")
public class ELConfig {
@Value("I Love You!")
private String normal;
@Value("#{systemProperties['os.name']}")
private String osName;
@Value("#{systemEnvironment['os.arch']}")
private String osArch;
@Value("#{T(java.lang.Math).random()*100}")
private double randomNumber;
@Value("#{demoService1.author}")
private String author;
@Value("t.txt")
private Resource testFile;
@Value("http://www.baidu.com")
private Resource testUrl;
@Value("${sang.username}")
private String su;
@Value("${sang.password}")
private String sp;
@Value("${sang.nickname}")
private String sn;
@Autowired
private Environment environment;
public void output() {
try {
System.out.println(normal);
System.out.println(osName);
System.out.println(osArch);
System.out.println(randomNumber);
System.out.println(author);
System.out.println(IOUtils.toString(testFile.getInputStream(),"UTF-8"));
//访问网址
System.out.println(IOUtils.toString(testUrl.getInputStream(),"UTF-8"));
//获取网址
System.out.println("testUrl.getURL():"+testUrl.getURL());
System.out.println(su);
System.out.println(sp);
System.out.println(sn);
System.out.println(environment.getProperty("sang.nickname"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
OK ,小伙伴们看到,我们首先需要在类上使用@PropertySource来指定文件地址,将t.properties注入。在属性上我们可以直接使用@Value来完成注入,可以注入普通的字符串,也可以执行一行Java代码,可以将某一个类的属性值注入,也可以注入一个文件,等,不赘述。我们注入的t.properties除了通过${aaa.bbb}获取之外,也可以从Environment中获得。
当然,我们还需要一个配置类,如下:
@Configuration
@ComponentScan("org.sang")
public class MyConfig {
}
5.运行
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
ELConfig bean = context.getBean(ELConfig.class);
bean.output();
context.close();
}
}
运行结果:
本案例下载地址
本案例GitHub地址
对于Bean的操作,很多情况下不是简单的创建,我们还需要做一些必要的初始化操作,同时,用完了,该销毁的销毁,该释放的释放,这个要怎么实现呢?
总的来说,有两种方式:
1.Java配置方式,我们可以使用@Bean的注解中的initMethod和destroyMethod两个东东,这两个对应xml配置文件中的init-method和destroy-method。
2.使用JSR-250中的注解@PostConstruct和@PreDestroy.
我们来看看这两个案例。
- 添加JSR-250支持
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
2.使用Java配置的方式操作Bean
public class BeanWayService {
public void init() {
System.out.println("BeanWayService-init()");
}
public BeanWayService() {
System.out.println("BeanWayService-构造方法");
}
public void destroy() {
System.out.println("BeanWayService-destroy()");
}
}
3.使用JSR-250的方式操作Bean
public class JSR250WayService {
@PostConstruct//构造方法执行之后执行
public void init() {
System.out.println("JSR250WayService-init()");
}
public JSR250WayService() {
System.out.println("JSR250WayService-构造方法");
}
@PreDestroy//销毁之前执行
public void destroy() {
System.out.println("JSR250WayService-destroy()");
}
}
4.编写配置类
@Configuration
public class MyConfig {
@Bean(initMethod = "init",destroyMethod = "destroy")
BeanWayService beanWayService() {
return new BeanWayService();
}
@Bean
JSR250WayService jsr250WayService() {
return new JSR250WayService();
}
}
initMethod指定在构造方法执行完成之后执行初始化方法,destroyMethod指定在销毁之前执行destroy方法。
5.运行
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
BeanWayService beanWayService = context.getBean(BeanWayService.class);
JSR250WayService jsr250WayService = context.getBean(JSR250WayService.class);
context.close();
}
}
运行结果:
本案例下载地址:
本案例GitHub地址
在开发中我们一个常见的需求是数据库的连接配置,在开发时数据库是一种配置方式,项目发布的时候数据库又是另外一种配置方式。对于这个问题,我们可以采用@Profile注解来简化在两种不同的配置中切换。OK,接下来我们来看看@Profile注解的使用。
1.创建示例Bean
public class DemoBean {
private String content;
public DemoBean(String content) {
super();
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
2.使用Profile配置
@Configuration
public class ProfileConfig {
@Bean
@Profile("dev")
public DemoBean devDemoBean() {
return new DemoBean("dev");
}
@Bean
@Profile("prod")
public DemoBean prodDemoBean() {
return new DemoBean("prod");
}
}
当Profile为dev时使用devDemoBean来实例化DemoBean,当Profile为prod时,使用prodDemoBean来实例化DemoBean。
3.使用
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("prod");
context.register(ProfileConfig.class);
context.refresh();
DemoBean bean = context.getBean(DemoBean.class);
System.out.println(bean.getContent());
context.close();
}
}
这里还是先获取Spring容器,这不过在获取容器时先不传入配置文件,待我们先将活动的Profile置为prod之后,再设置配置文件,设置成功之后,一定要刷新容器。
运行结果:
本案例下载地址:
有的时候,我们可能希望当一个Bean完成某一项操作的时候,能够通知到其他的Bean,其他Bean收到消息后做出相应的处理。Spring对此也提供了相应的支持,在Spring框架内我们可以很好的完成事件的发送与接收。
1.定义消息载体
public class DemoEvent extends ApplicationEvent{
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;
}
}
2.定义事件监听器
@Component
public class DemoListener implements ApplicationListener<DemoEvent> {
public void onApplicationEvent(DemoEvent demoEvent) {
System.out.println("我收到DemoEvent的事件了:"+demoEvent.getMsg());
}
}
3.定义事件发布者
@Component
public class DemoPublish{
@Autowired
ApplicationContext applicationContext;
public void publish(String msg) {
applicationContext.publishEvent(new DemoEvent(this,msg));
}
}
4.配置类
@Configuration
@ComponentScan("org.sang")
public class MyConfig {
}
5.运行
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
DemoPublish demoPublish = context.getBean(DemoPublish.class);
demoPublish.publish("Hello sang !");
context.close();
}
}
运行结果:
本案例下载地址:
OK,以上就是Spring中一些常见的配置。
参考资料:
《JavaEE开发的颠覆者 Spring Boot实战》第二章
文章浏览阅读1w次,点赞19次,收藏99次。在完成用arbotix测试机械臂后,我们想控制真实的机械臂伺服电机。由于arbotix是针对舵机的,我们要想控制伺服电机,要将ROS里机械臂的关节信息(角度、角速度、加速度、力等)发给下位机,首先就是要获取关节信息。 关于让机械臂动起来,这里参考了一些大神的博客,在这里表示感谢让模型动起来: http://blog.csdn.net/yaked/article/details_airbot_play/joint_states
文章浏览阅读1.8k次。1.SSH安装:$ sudo apt-get ssh该远程控制只能使用命令行控制,但是使用方便延迟低。ubuntu18.04下一般自带,win10需要下载putty使用。连接命令:$ ssh username@host_address#username为服务器名,host_address为服务器ip地址ubuntu下使用SSH向服务器下载或上传文件。下载文件命令:$ scp username@host_address:file_name上传命令:$ scp file_name u_ssh和远程桌面 哪个延迟低
文章浏览阅读7.6k次,点赞5次,收藏12次。Tornado是Python界中非常出名的一款Web框架,和Flask一样它也属于轻量级的Web框架。_python tornado
文章浏览阅读854次。转自:https://www.cnblogs.com/lylife/p/5519109.html项目之前都是好好的,最近现场那边出现一个问题,报错不是合法的json字符串,这个json字符串是通过http请求访问获得的。 通过直接在浏览器上直接访问http这个请求,发现返回的json也是完全正确的。后来排查代码才发现了原来错误出在从字节流中读取数据这里: 看下之前出错代码:这..._inputstream.read(byte[])' on a null object reference
文章浏览阅读3.6k次,点赞6次,收藏45次。仿真(2,1,2)卷积码的性能,BCJR译码,级联的调制方式采用QPSK。每个码块信息比特长度为1000,要求编码最终状态归0。要求输出的结果为译码后信息比特的BER。_matlab bcjr
文章浏览阅读1.5k次。“欢迎关注【雷哥office】,为了回馈粉丝,最近几个月每周都会有送书活动,想要书的朋友不要错过哦~本周第二弹福利, 详情见文末”1使用鼠标⑴选中区域。将鼠标光标放在要选择的文本的开始位置,按住鼠标左键并拖曳,这时选中的文本会以阴影的形式显示,选择完成后,释放鼠标左键,鼠标光标经过的文字就被选定了。⑵选中词语。将鼠标光标移动到某个词语或单词中间,双击鼠标左键即可选中该词语或单词。⑶..._python获取鼠标选取的内容
文章浏览阅读505次。正态分布广泛存在于自然现象、生产、生活的方方面面,例如试卷命题难度,产品的使用寿命、农作物产量、气温、降水量、工资收入、人类的身高体重肺活量,甚至颜值……关于正态分布的数学定义及各种性质,不在此赘述。简单理解,就是“两头小,中间大”,比如长相奇丑无比和倾国倾城的人都是少数,绝大多数人都属于大众脸。很多时候,在进行数据分析工作时,首先要看的就是数据是服从何种概率分布,而正态分布则是最重要的一种概率分..._怎么制作散点图表示采样个体在全部个体中的分布位置
文章浏览阅读1.9k次。C/C++的main函数除了常见的argc、argv,还具有第三个指定的参数envp,完整的引用方式如下:main(int argc, const char *argv[], const char *envp[]) //void类型没有参数1.argc为整数2.argv为指针的指针(可理解为:char **argv or: char *argv[] or: char argv..._cpp main第三个参数是啥
文章浏览阅读2.9w次,点赞4次,收藏24次。这里实现的 FTP 转发,其实和 SFTP 转发是一样的。详情见我的另一篇文章 Nginx代理转发SFTP上次写的 代理转发 SFTP 是在 linux 上测试的,本篇文章则是在 Windows 环境下测试的。关于 Windows 环境怎么搭建 FTP 服务器,请参阅我的另一篇文章 图解 —— Windows 下 FTP 服务器搭建及验证全过程配置文件同样打开 nginx.conf 配置文件,做如下配置,和SFTP的转发配置完全一样stream { upstream ftp{ ._ftp nginx转发
文章浏览阅读7.5k次,点赞2次,收藏13次。最近在学习STATA做分析的时候,发现这个软件很多功能很强大,但是背后的统计学知识要求也比较高,作为一边深入学习统计知识一遍用软件的小白,好多东西只是知其然不知其所以然,因此尝试自己把STATA的一些运算分解出来。因此这里记录一下学习内容。在做STATA的主成分分析和因子分析的时候,觉得这两个东西很像,但是其中的原理好像也不太清楚,网上查了一些文章,花了不少时间才明白怎么做的,这里演示一下具体_stata主成分分析结果解读
文章浏览阅读338次。为什么需要JavaEE我们编写的JSP代码中,由于大量的显示代码和业务逻辑混淆在一起,彼此嵌套,不利于程序的维护和扩展。当业务需求发生变化的时候,对于程序员和美工都是一个很重的负担。为了程序的易维护性和可扩展性,这就需要我们使用JavaEE技术来进行项目开发2、 什么是JavaEEJavaEE是一个开发分布式企业级应用的规范和标准。Java语言的平台有3个版本:适用于小型设备和智能卡的JavaME(Java Platform Micro Edition,Java微型版)、适用于桌面系统的Java_javaee的学习摘要
文章浏览阅读316次。DM大规模并行处理MPP_dm mpp