zoukankan      html  css  js  c++  java
  • Spring常用配置

    上篇文章我们简单介绍了Spring的基本配置,算是一个简单的入门,这篇文章我们再一起来看看Spring在使用的过程中一些其他的常见配置。

    Bean的Scope

    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 {
    
    }

    这个时候再运行,结果如下:

    本案例下载地址:

    本案例GitHub地址

    Spring EL和资源调用

    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的初始化和销毁

    对于Bean的操作,很多情况下不是简单的创建,我们还需要做一些必要的初始化操作,同时,用完了,该销毁的销毁,该释放的释放,这个要怎么实现呢?
    总的来说,有两种方式:

    1.Java配置方式,我们可以使用@Bean的注解中的initMethod和destroyMethod两个东东,这两个对应xml配置文件中的init-method和destroy-method。
    2.使用JSR-250中的注解@PostConstruct和@PreDestroy.

    我们来看看这两个案例。

    1. 添加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问题

    在开发中我们一个常见的需求是数据库的连接配置,在开发时数据库是一种配置方式,项目发布的时候数据库又是另外一种配置方式。对于这个问题,我们可以采用@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之后,再设置配置文件,设置成功之后,一定要刷新容器。
    运行结果:

    本案例下载地址:

    本案例GitHub地址

    Spring中的事件传递

    有的时候,我们可能希望当一个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();
        }
    }

    运行结果:

    本案例下载地址:

    本案例GitHub地址

    OK,以上就是Spring中一些常见的配置。

    参考资料:
    《JavaEE开发的颠覆者 Spring Boot实战》第二章

  • 相关阅读:
    微信小程序 单选按钮 最佳
    微信小程序 单选按钮的实现
    微信小程序 单选框实现
    Java Code To Create Pyramid and Pattern
    Java language
    npm Err! Unexpected end of JSON input while parsing near
    Node.js Express FrameWork Tutorial
    Higher-Order Function Examples
    Create First HTTP Web Server in Node.js: Complete Tutorial
    Node.js NPM Tutorial: Create, Publish, Extend & Manage
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461647.html
Copyright © 2011-2022 走看看