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

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

通过注解设定Bean的作用域

1、Spring预定义作用域

xml形式

<bean id="bean" class="com.demo.ioc.Person" scope="singleton"/>

注解形式

@Component
@Scope("singleton")  // prototype
public class Person {
}
// 或者
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
    @Bean
    @Scope("singleton")
    public Person person() {
        return new Person();
    }

2、自定义Scope作用域

回忆之前的自定义Scope代码

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

xml形式

<!-- 1、将Scope交由Spring管理 -->
<bean id="myScope" class="com.demo.ioc.MyScope"/>
<!-- 2、配置 -->
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="scopes">
        <map>
            <entry key="myScope" value-ref="myScope"/>
        </map>
    </property>
</bean>
<!-- 3、使用 -->
<bean class="com.demo.ioc.Bean" id="bean" scope="myScope"/>

注解形式

package com.demo.ioc;
import org.springframework.beans.factory.config.CustomScopeConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
// 创建配置文件,可以认为是一个xml配置文件
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
    // 1、交由Spring管理
    @Bean
    public MyScope myScope(){
        return new MyScope();
    }
    // 2、配置
    @Bean
    public CustomScopeConfigurer customScopeConfigurer(){
        CustomScopeConfigurer configurer = new CustomScopeConfigurer();
        configurer.addScope("myScope", myScope());
        return configurer;
    }
    // 3、使用
    @Bean
    @Scope("myScope")
    public Person person() {
        return new Person();
    }
}

测试

package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class BeanTest {
    @Test
    public void testBean() {
        // 获取上下文
        ApplicationContext context =
                new AnnotationConfigApplicationContext(MyConfiguration.class);
        // 获取Bean
        for (int i = 0; i < 10; i++) {
            Person bean = context.getBean("person", Person.class);
            System.out.println(bean);
        }
    }
}

Bean注解的方式进行方法注入

回顾方法注入场景:

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();
}

xml方式


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

注解形式

package com.demo.ioc;
@Component
@Scope("prototype")
public class Bean2 {
}
package com.demo.ioc;
@Component
public abstract class Bean1 {
    @Lookup
    protected abstract Bean2 createBean2();
}

通过注解开启Bean的懒加载

xml形式

<!-- 单个 -->
<bean class="com.demo.ioc.Bean" id="bean" lazy-init="true"/>
<!-- 全局 -->
<beans default-lazy-init="true"></beans>

注解形式

/**
 * 单个
 */
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
    @Bean
    @Lazy
    public Person person() {
        return new Person();
    }
}
// 或者
@Component
@Lazy
public class Person {
}
/**
 * 全局
 */
@Configuration
@ComponentScan(value = "com.demo.ioc")
@Lazy
public class MyConfiguration {
    @Bean
    public Person person() {
        return new Person();
    }
}

通过注解编写Bean初始化及销毁

配置文件

package com.demo.ioc;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
// 创建配置文件,可以认为是一个xml配置文件
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
}

上下文测试

package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
public class BeanTest {
    @Test
    public void testBean() {
        // 获取上下文
        AbstractApplicationContext context =
                new AnnotationConfigApplicationContext(MyConfiguration.class);
        Person bean = context.getBean("person", Person.class);
        context.close();
    }
}

方式一:

package com.demo.ioc;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class Person implements InitializingBean, DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("Person.destroy");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Person.afterPropertiesSet");
    }
}

方式二:

package com.demo.ioc;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class Person {
    @PostConstruct
    public void onInit(){
        System.out.println("Person.onInit");
    }
    @PreDestroy
    public void onDestroy(){
        System.out.println("Person.onDestroy");
    }
}

方式三

package com.demo.ioc;
public class Person {
    public void onInit() {
        System.out.println("Person.onInit");
    }
    public void onDestroy() {
        System.out.println("Person.onDestroy");
    }
}

通过Bean设置参数

package com.demo.ioc;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
    @Bean(initMethod = "onInit", destroyMethod = "onDestroy")
    public Person person() {
        return new Person();
    }
}
相关文章
|
4月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
5月前
|
人工智能 Java API
构建基于Java的AI智能体:使用LangChain4j与Spring AI实现RAG应用
当大模型需要处理私有、实时的数据时,检索增强生成(RAG)技术成为了核心解决方案。本文深入探讨如何在Java生态中构建具备RAG能力的AI智能体。我们将介绍新兴的Spring AI项目与成熟的LangChain4j框架,详细演示如何从零开始构建一个能够查询私有知识库的智能问答系统。内容涵盖文档加载与分块、向量数据库集成、语义检索以及与大模型的最终合成,并提供完整的代码实现,为Java开发者开启构建复杂AI智能体的大门。
2760 58
|
4月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
290 8
|
5月前
|
监控 Java 数据库
从零学 Dropwizard:手把手搭轻量 Java 微服务,告别 Spring 臃肿
Dropwizard 整合 Jetty、Jersey 等成熟组件,开箱即用,无需复杂配置。轻量高效,启动快,资源占用少,内置监控、健康检查与安全防护,搭配 Docker 部署便捷,是构建生产级 Java 微服务的极简利器。
494 3
|
6月前
|
前端开发 Java 开发者
Java新手指南:在Spring MVC中使用查询字符串与参数
通过结合实际的需求和业务逻辑,开发者可以灵活地利用这些机制,为用户提供更丰富而高效的Web应用体验。
214 15
|
7月前
|
安全 Java 微服务
Java 最新技术和框架实操:涵盖 JDK 21 新特性与 Spring Security 6.x 安全框架搭建
本文系统整理了Java最新技术与主流框架实操内容,涵盖Java 17+新特性(如模式匹配、文本块、记录类)、Spring Boot 3微服务开发、响应式编程(WebFlux)、容器化部署(Docker+K8s)、测试与CI/CD实践,附完整代码示例和学习资源推荐,助你构建现代Java全栈开发能力。
822 1
|
6月前
|
Cloud Native Java API
Java Spring框架技术栈选和最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡
Java Spring框架技术栈选和最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡
1262 0
|
9月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
267 2
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
317 1
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)