springboot原理实战(1)--注解方式装配bean

简介: springboot原理实战(1)--注解方式装配bean


现在先了解下,具体的几种注入bean到spring的方式。

也就是来玩一下这个 AnnotationConfigApplicationContext这个类:


1.@Configurable


@Configurable
public class MyConfig {}

测试:


public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        System.out.println(context.getBean(MyConfig.class));
    }


context.getBean有多种方式拿到bean,根据类class,类型等,

结果显示:容器拿到了这个bean:

1dc618a0ed9580ce8bfa6facb208c08f.png


2.@Bean


a.@bean注入


写个bean


public class MyBean {
}


在配置类中@Bean注入,scope配置指定单个或者多个实例方式注入


@Bean(name = "mybean")
@Scope("prototype")
 public MyBean createMyBean(){
     return new MyBean();
 }


b.通过工厂方式注入


①官方提供,实现FactoryBean方式


public class RunableFactoryBean implements FactoryBean<Jeep> {
    @Override
    public Jeep getObject() throws Exception {
        return new Jeep();
    }
    @Override
    public Class<?> getObjectType() {
        return Jeep.class;
    }
    @Override
    public boolean isSingleton() {
        return true;
    }
}


@Configurable
public class MyConfig {
    @Bean
    public RunableFactoryBean createRunnableFactoryBean(){
        return new RunableFactoryBean();
    }
}


测试,测试1:拿到工厂(用&符号前缀),测试2:拿到工厂创建的bean


public class Test1 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        System.out.println(context.getBean("&createRunnableFactoryBean"));
        System.out.println(context.getBean(Jeep.class));
    }
}


结果打印,都拿到了:

5d4c6812c8535adbb050f4ddf2e1bce8.png


②自定义工厂方式


public class Car {
}


public class JeepFactory {
    public Car create(){
        return new Car();
    }
}


先注入工厂,在通过工厂拿到bean


@Configurable
public class MyConfig {
    @Bean
    public JeepFactory creatJeepFactory(){
        return new JeepFactory();
    }
    @Bean
    public Car createJeep(JeepFactory factory){
        return factory.create();
    }
}


测试:略


3.初始化bean前后做一些事情:


在初始化后和销毁的时候调用一些方法:


1)方式1:实现InitializingBean(初始化后触发), DisposableBean(销毁的时候触发)


public class Cat implements InitializingBean, DisposableBean {
    public Cat() {
        System.out.println("=======init cat=========");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("=======afterPropertiesSet=========");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("=======destroy=========");
    }
}


2)方式2:根据@Bean注解属性配置:


public class Dog {
    public void init(){
        System.out.println("init");
    }
    public void destory(){
        System.out.println("destory");
    }
}


@Bean(initMethod="init",destroyMethod="destory")
    public Dog createDog(){
        return new Dog();
    }


3)方式3:@PostContruct


public class Animal {
    @PostConstruct
    public void inital(){
        System.out.println("------initial--------");
    }
    @PreDestroy
    public void close(){
        System.out.println("------close--------");
    }
}


4.组件注入方式


①普通组件@Component


@Component("myUser")
public class User {}


②Resposity ,常用于数据库处理bean


@Repository
public class UserDao {
}


③@Service,常用于业务处理类


@Service
public class UserService {
}


④@controller,常用于请求控制类


@Controller
public class UserController {
}


测试:


public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class, User.class, UserDao.class,
                UserService.class, UserController.class);
        System.out.println(context.getBean(UserDao.class));
        System.out.println(context.getBean(UserService.class));
        System.out.println(context.getBean(UserController.class));
        context.close();
    }
}


运行结果:

5d4c6812c8535adbb050f4ddf2e1bce8.png


5.依赖注入装配bean的方式


① @Autowire


如果多个bean,可以用@Quitifier(“XX”)具体指定,也可使用@Primary提高bean的优先级。


@Controller
public class UserController {
    @Autowired
    private UserDao userDao;
}


@Bean(name = "mybean")
    @Primary
    public MyBean createMyBean(){
        return new MyBean();
    }


②@Resource JSR 250的方式


@Controller
public class UserController {
    @Autowired
    private UserDao userDao;
    @Resource
    private UserService userService;
}


③@Inject JSR-330的方式


需要导包,因为spring项目默认不支持。


<dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>


import org.springframework.stereotype.Component;
import javax.inject.Inject;
@Component("myUser")
public class User {
    //JSR-330
    @Inject
    private Cat cat;
    @Override
    public String toString() {
        return "User{" +
                "cat=" + cat +
                '}';
    }
}


6.组件注入需要扫描包支持,如何扫描包?


方式1,在AnnotationConfigApplicationContext上直接写报名:


46a9d80a6e05e4e3b19d57a0ee70bcdf.png

public class AnnocationClient {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.springboot.demo1",
                "com.springboot.demo2");
        System.out.println(context.getBean(User.class));
        System.out.println(context.getBean(UserDao.class));
        System.out.println(context.getBean(UserController.class));
        context.close();
    }
}


方式2:扫描配置类::


可以写个扫描配置类:

66ba272a0bfc97be54a5fa679e3d5482.png

@ComponentScan(basePackages = "com.springboot.demo1", excludeFilters= @Filter(type = FilterType.ASSIGNABLE_TYPE,classes={DogConfig.class}))
@Configurable
public class AnnocationScan {
}


注意,这里可以选择排除excludeFilters,后面说明咋排除。


public class AnnocationClient2 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnocationScan.class);
//        System.out.println(context.getBean(RunableFactoryBean.class));
        System.out.println(context.getBean(User.class));
        System.out.println(context.getBean(UserDao.class));
//        System.out.println(context.getBean(Cat.class));
        System.out.println(context.getBean(UserController.class));
    }
}


配置排除的包:

88b9988b40447cb37c7e3c492d49867f.png

点击排除的枚举类:


public enum FilterType {
    ANNOTATION, //通过注解排除
    ASSIGNABLE_TYPE, //通过指定的类排除
    ASPECTJ, //通过aspectj表达式排除
    REGEX, //通过正则表达式排除
    CUSTOM; //自定义接口,实现org.springframework.core.type.filter.TypeFilter}排除
    private FilterType() {
    }
}


上面的截图是使用的ASSIGNABLE_TYPE自定类方式。


相关文章
|
12月前
|
缓存 监控 Java
SpringBoot @Scheduled 注解详解
使用`@Scheduled`注解实现方法周期性执行,支持固定间隔、延迟或Cron表达式触发,基于Spring Task,适用于日志清理、数据同步等定时任务场景。需启用`@EnableScheduling`,注意线程阻塞与分布式重复问题,推荐结合`@Async`异步处理,提升任务调度效率。
1679 128
|
11月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1515 2
Spring Boot 3.x 微服务架构实战指南
|
12月前
|
消息中间件 Ubuntu Java
SpringBoot整合MQTT实战:基于EMQX实现双向设备通信
本教程指导在Ubuntu上部署EMQX 5.9.0并集成Spring Boot实现MQTT双向通信,涵盖服务器搭建、客户端配置及生产实践,助您快速构建企业级物联网消息系统。
3229 1
|
11月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
698 4
|
11月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
849 2
|
12月前
|
XML Java 数据格式
常用SpringBoot注解汇总与用法说明
这些注解的使用和组合是Spring Boot快速开发和微服务实现的基础,通过它们,可以有效地指导Spring容器进行类发现、自动装配、配置、代理和管理等核心功能。开发者应当根据项目实际需求,运用这些注解来优化代码结构和服务逻辑。
746 12
|
Java 应用服务中间件 Maven
传统maven项目和现在spring boot项目的区别
Spring Boot:传统 Web 项目与采用 Spring Boot 项目区别
963 0
传统maven项目和现在spring boot项目的区别
|
XML Java 数据库连接
创建springboot项目的基本流程——以宠物类别为例
创建springboot项目的基本流程——以宠物类别为例
383 0
创建springboot项目的基本流程——以宠物类别为例
|
存储 机器学习/深度学习 IDE
SpringBoot 项目与被开发快速迁移|学习笔记
快速学习 SpringBoot 项目与被开发快速迁移
SpringBoot 项目与被开发快速迁移|学习笔记
|
Java Spring
自定义SpringBoot项目的启动Banner
``Banner``是``SpringBoot``框架一个特色的部分,其设计的目的无非就是一个框架的标识,其中包含了版本号、框架名称等内容,既然``SpringBoot``为我们提供了这个模块,它肯定也是可以更换的这也是``Spring``开源框架的设计理念。