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();
    }
}
相关文章
|
3月前
|
Java 关系型数据库 MySQL
Spring Boot自动配置:魔法背后的秘密
Spring Boot 自动配置揭秘:只需简单配置即可启动项目,背后依赖“约定大于配置”与条件化装配。核心在于 `@EnableAutoConfiguration` 注解与 `@Conditional` 系列条件判断,通过 `spring.factories` 或 `AutoConfiguration.imports` 加载配置类,实现按需自动装配 Bean。
|
3月前
|
缓存 监控 Java
SpringBoot @Scheduled 注解详解
使用`@Scheduled`注解实现方法周期性执行,支持固定间隔、延迟或Cron表达式触发,基于Spring Task,适用于日志清理、数据同步等定时任务场景。需启用`@EnableScheduling`,注意线程阻塞与分布式重复问题,推荐结合`@Async`异步处理,提升任务调度效率。
612 128
|
3月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
1401 0
|
2月前
|
前端开发 Java 应用服务中间件
《深入理解Spring》 Spring Boot——约定优于配置的革命者
Spring Boot基于“约定优于配置”理念,通过自动配置、起步依赖、嵌入式容器和Actuator四大特性,简化Spring应用的开发与部署,提升效率,降低门槛,成为现代Java开发的事实标准。
|
2月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
444 2
|
3月前
|
XML Java 数据格式
常用SpringBoot注解汇总与用法说明
这些注解的使用和组合是Spring Boot快速开发和微服务实现的基础,通过它们,可以有效地指导Spring容器进行类发现、自动装配、配置、代理和管理等核心功能。开发者应当根据项目实际需求,运用这些注解来优化代码结构和服务逻辑。
330 12
|
3月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
631 5
|
3月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
205 0
探索Spring Boot的@Conditional注解的上下文配置
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
388 6
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
733 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)