Java笔记:Spring配置xml和注解(3)

简介: Java笔记:Spring配置xml和注解

Bean作用域

  • singleton作用域(单例,限定在一个上下文环境中)
  • prototype作用域(多例)
  • Web环境作用域
  • request作用域
  • session作用域
  • application作用域
  • websocket作用域
  • 自定义作用域
  • SimpleThreadScope作用域
<!-- 单例 默认singleton -->
<bean id="bean" class="com.demo.ioc.Bean"/>
<!-- 多例 -->
<bean id="bean" class="com.demo.ioc.Bean" scope="prototype"/>

总结


配置


<bean id="bean2" class="com.demo.ioc.Bean2" scope="prototype"/>


<bean id="bean1" class="com.demo.ioc.Bean1">

   <property name="bean2" ref="bean2"/>

</bean>


image.png

方法注入

场景:

Bean1是singleton, Bean2是prototype, Bean1依赖于Bean2

我们希望每次调用Bean1某个方法时候,该方法每次拿到Bean2都是新的实例

package com.demo.ioc;
public class Bean2 {
}
package com.demo.ioc;
public abstract class Bean1 {
    protected abstract Bean2 createBean2();
}
<bean id="bean2" class="com.demo.ioc.Bean2" scope="prototype"/>
<bean id="bean1" class="com.demo.ioc.Bean1" scope="singleton">
    <lookup-method name="createBean2" bean="bean2"/>
</bean>

Web环境作用域

项目结构

$ tree
.
├── pom.xml
└── src
   └── main
      ├── java
      │   └── com
      │       └── demo
      │           ├── ApplicationController.java
      │           ├── RequestController.java
      │           └── SessionController.java
      ├── resources
      │   └── spring.xml
      └── webapp
          └── WEB-INF
              └── web.xml

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>spring-mvc</groupId>
    <artifactId>com.demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--打包方式为war-->
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
    </dependencies>
</project>

web.xml

<?xml version="1.0" encoding="utf-8" ?>
<web-app version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
>
    <!-- 建立SpringWeb上下文环境-->
    <servlet>
        <servlet-name>SpringServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

RequestController.java

package com.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class RequestController {
    @RequestMapping("/request")
    @ResponseBody
    public String test(){
        return this.toString();
    }
}

SessionController.java

package com.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SessionController {
    @RequestMapping("/session")
    @ResponseBody
    public String test(){
        return this.toString();
    }
}

ApplicationController.java

package com.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ApplicationController {
    @RequestMapping("/application")
    @ResponseBody
    public String test(){
        return this.toString();
    }
}


总结


reuqest:每个request请求都会创建一个单独的实例。


session:每个session都会创建一个单独的实例。


application:每个sercletContext都会创建一个单独的实例。


websocket:每个websocket链接都会创建一个单独的实例。


自定义作用域

双例模式

package com.demo.ioc;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 自定义作用域
 * 实现双例模式(每一个Bean对应两个实例)
 */
public class MyScope implements Scope {
    Map<String, Object> map1 = new ConcurrentHashMap<>();
    Map<String, Object> map2 = new ConcurrentHashMap<>();
    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        //先从map1取
        if (!map1.containsKey(name)) {
            Object obj = objectFactory.getObject();
            map1.put(name, obj);
            return obj;
        }
        //再从map2取
        if (!map2.containsKey(name)) {
            Object obj = objectFactory.getObject();
            map2.put(name, obj);
            return obj;
        }
        // 如果map1和map2中都存在则随机返回
        int i = new Random().nextInt(2);
        if (i == 0) {
            return map1.get(name);
        } else {
            return map2.get(name);
        }
    }
    @Override
    public Object remove(String name) {
        // 和添加顺序正好相反
        if(map2.containsKey(name)){
            Object obj = map2.get(name);
            map2.remove(name);
            return obj;
        }
        if(map1.containsKey(name)){
            Object obj = map1.get(name);
            map1.remove(name);
            return obj;
        }
        return null;
    }
    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
    }
    @Override
    public Object resolveContextualObject(String key) {
        return null;
    }
    @Override
    public String getConversationId() {
        return null;
    }
}
package com.demo.ioc;
public class Bean {
}
<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/jee
                        http://www.springframework.org/schema/jee/spring-jee.xsd">
    <bean id="myScope" class="com.demo.ioc.MyScope"/>
    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="myScope" value-ref="myScope"/>
            </map>
        </property>
    </bean>
    <bean class="com.demo.ioc.Bean" id="bean" scope="myScope"/>
</beans>

测试

package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest {
    @Test
    public void testBean(){
        // 获取上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        for (int i = 0; i < 10; i++) {
            Bean bean = context.getBean("bean", Bean.class);
            System.out.println(bean);
        }
    }
}
相关文章
|
7月前
|
负载均衡 监控 Java
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
本文详细介绍了 Spring Cloud Gateway 的核心功能与实践配置。首先讲解了网关模块的创建流程,包括依赖引入(gateway、nacos 服务发现、负载均衡)、端口与服务发现配置,以及路由规则的设置(需注意路径前缀重复与优先级 order)。接着深入解析路由断言,涵盖 After、Before、Path 等 12 种内置断言的参数、作用及配置示例,并说明了自定义断言的实现方法。随后重点阐述过滤器机制,区分路由过滤器(如 AddRequestHeader、RewritePath、RequestRateLimiter 等)与全局过滤器的作用范围与配置方式,提
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
|
7月前
|
Java 关系型数据库 MySQL
Spring Boot自动配置:魔法背后的秘密
Spring Boot 自动配置揭秘:只需简单配置即可启动项目,背后依赖“约定大于配置”与条件化装配。核心在于 `@EnableAutoConfiguration` 注解与 `@Conditional` 系列条件判断,通过 `spring.factories` 或 `AutoConfiguration.imports` 加载配置类,实现按需自动装配 Bean。
|
7月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
2438 0
|
9月前
|
Java Spring
Spring Boot配置的优先级?
在Spring Boot项目中,配置可通过配置文件和外部配置实现。支持的配置文件包括application.properties、application.yml和application.yaml,优先级依次降低。外部配置常用方式有Java系统属性(如-Dserver.port=9001)和命令行参数(如--server.port=10010),其中命令行参数优先级高于系统属性。整体优先级顺序为:命令行参数 &gt; Java系统属性 &gt; application.properties &gt; application.yml &gt; application.yaml。
1232 0
|
6月前
|
前端开发 Java 应用服务中间件
《深入理解Spring》 Spring Boot——约定优于配置的革命者
Spring Boot基于“约定优于配置”理念,通过自动配置、起步依赖、嵌入式容器和Actuator四大特性,简化Spring应用的开发与部署,提升效率,降低门槛,成为现代Java开发的事实标准。
|
7月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
1218 5
|
7月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
365 0
探索Spring Boot的@Conditional注解的上下文配置
|
8月前
|
安全 算法 Java
在Spring Boot中应用Jasypt以加密配置信息。
通过以上步骤,可以在Spring Boot应用中有效地利用Jasypt对配置信息进行加密,这样即使配置文件被泄露,其中的敏感信息也不会直接暴露给攻击者。这是一种在不牺牲操作复杂度的情况下提升应用安全性的简便方法。
1363 10
|
9月前
|
人工智能 安全 Java
Spring Boot yml 配置敏感信息加密
本文介绍了如何在 Spring Boot 项目中使用 Jasypt 实现配置文件加密,包含添加依赖、配置密钥、生成加密值、在配置中使用加密值及验证步骤,并提供了注意事项,确保敏感信息的安全管理。
1483 1
|
9月前
|
SQL XML Java
配置Spring框架以连接SQL Server数据库
最后,需要集成Spring配置到应用中,这通常在 `main`方法或者Spring Boot的应用配置类中通过加载XML配置或使用注解来实现。
679 0