spring注解驱动开发(IOC功能)

一.IOC功能

1.传统方式

(1) 在classpath下创建beans.xml

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 包扫描,只要类标注了@Controller,@Service,@Repository,@Component -->
    <!-- 扫描 com.miracle 下的组件-->
    <context:component-scan base-package="com.miracle"></context:component-scan>
    <bean id="person" class="com.miracle.springAnnotation.bean.Person">
        <property name="age" value="18"></property>
        <property name="name" value="zhangsan"></property>
    </bean>
</beans>

(2)编写bean

package com.miracle.springAnnotation.bean;

public class Person {

    private String name;
    private Integer age;

    public Person() {

    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

(3)使用bean

package com.miracle.springAnnotation;

import com.miracle.springAnnotation.bean.Person;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person);
    }
}

2.注解方式

(1)创建配置类(等同于原来的配置文件)

package com.miracle.springAnnotation.config;

import com.miracle.springAnnotation.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

// 配置类 等同于 配置文件
@Configuration // 告诉Spring这是一个配置类
@ComponentScan(value = "com.miracle")  // 开启包扫描,扫描定义在 com.miracle 下的包
public class MainConfig {

    // 默认的是单例的,通过@Scope注解的值来修改
    // @Scope("prototype") 多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象
    // @Scope("singleton") 单实例的:ioc容器启动会调用方法创建对象放到ioc容器中
    // 给容器中注册一个Bean,类型为返回值的类型,id默认是用方法名作为id,@Bean("id") 来指定bean的id
    // @Lazy 懒加载bean
    @Scope("prototype")
    @Bean
    public Person person() {

        return new Person("lisi", 20);
    }
}

(2)使用bean

package com.miracle.springAnnotation;

import com.miracle.springAnnotation.bean.Person;
import com.miracle.springAnnotation.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {

    public static void main(String[] args) {
        // 创建注解类型的 ApplicationContext 传入注解配置文件的class对象
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
        Person person = context.getBean(Person.class);
        System.out.println(person);
        
        // 通过类型,获取容器中这个类型的所有bean的名字
        String[] namesForType = context.getBeanNamesForType(Person.class);
        for (String name : namesForType) {
            System.out.println(name);
        }
    }
}

3.组件注册相关注解说明

(1)懒加载

针对单实例bean,默认在容器启动的时候创建对象
设置懒加载后,容器启动不创建对象,第一次获取bean时创建对象,并初始化

package com.miracle.springAnnotation.config;

import com.miracle.springAnnotation.bean.Person;
import org.springframework.context.annotation.*;

@Configuration
@ComponentScan(value = "com.miracle")
public class MainConfig2 {

    @Lazy  // 懒加载bean
    @Bean
    public Person person() {
        return new Person("lisi", 20);
    }
}
(2)按照条件注册bean

@Conditional:按照一定的条件进行判断,满足条件给容器中注册bean

假设有个需求是按照操作系统的不同(Linux/windows),给容器中注册不同的bean

在这里插入图片描述
通过查看Conditional注解的定义,可以知道这个注解可以加在类和方法上
所以我们在配置类中的方法里创建bean,所以将其加在方法上
查看注解接收参数 Class<? extends Condition>[] value();
可知注解接收 condition 数组
在这里插入图片描述
查看condition源码,发现是一个接口,包含一个matches方法,返回boolean值

在condition包下创建 condition实现类
WindowsCondition.java

package com.miracle.springAnnotation.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

/**
 * 判断操作系统是否windows系统
 */
public class WindowsCondition implements Condition {

    /**
     * @param context :判断条件能使用的上下文(环境)
     * @param metadata:注释信息
     * @return
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 判断是否是windows系统
        String osName = context.getEnvironment().getProperty("os.name");
        if(osName.contains("Windows")) {
            return true;
        }
        return false;
    }
}

LinuxCondition.java

package com.miracle.springAnnotation.condition;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

/**
 * 判断操作系统是否linux系统
 */
public class LinuxCondition implements Condition {

    /**
     * @param context :判断条件能使用的上下文(环境)
     * @param metadata:注释信息
     * @return
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 判断是否是linux系统
        String osName = context.getEnvironment().getProperty("os.name");
        if(osName.contains("linux")) {
            return true;
        }
        return false;
    }
}

MainConfig2.java
在配置类中创建bean的方法上加 @Conditional 注解

package com.miracle.springAnnotation.config;

import com.miracle.springAnnotation.bean.Person;
import com.miracle.springAnnotation.condition.LinuxCondition;
import com.miracle.springAnnotation.condition.WindowsCondition;
import org.springframework.context.annotation.*;

@Configuration
@ComponentScan(value = "com.miracle")
public class MainConfig2 {

    /**
     *  需求:根据操作系统的不同,注册不同的bean,windows注册bill,linux注册linus
     *
     */
    @Conditional({WindowsCondition.class})
    @Bean
    public Person bill() {
        return new Person("Bill Gates", 62);
    }

    @Conditional({LinuxCondition.class})
    @Bean
    public Person linus() {
        return new Person("linus", 48);
    }
}
如果@Conditional注解加到类上时,对类中组件统一设置,只有满足当前条件,这个类中配置的所有bean注册才能生效
(3)用@Import 注解向容器中导入bean

第一种方式:

package com.miracle.springAnnotation.config;

import com.miracle.springAnnotation.bean.Color;
import com.miracle.springAnnotation.bean.Red;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@ComponentScan(value = "com.miracle")
@Import({Color.class, Red.class})  //Import 向容器中导入组件,id默认是组件的全类名
public class MainConfig3 {


}

第二种方式:
编写selector

package com.miracle.springAnnotation.config;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

// 需要实现 ImportSelector 接口
public class MyImportSelector implements ImportSelector {
    // 自定义逻辑返回需要导入的组件
    // 返回值,就是要导入到容器中的组件全类名的数组
    // AnnotationMetadata : 当前标注 @Import注解的类的所有注解信息
    @Override
    public String[] selectImports(AnnotationMetadata AnnotationMetadata) {
        return new String[]{"com.miracle.springAnnotation.bean.Red", "com.miracle.springAnnotation.bean.Yellow", "com.miracle.springAnnotation.bean.Blue"};
    }
}

在配置类中导入selector

package com.miracle.springAnnotation.config;


import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@ComponentScan(value = "com.miracle")
@Import({MyImportSelector.class})  //导入selector
public class MainConfig3 {


}

第三种方式:
编写 definitionRegistry

package com.miracle.springAnnotation.config;

import com.miracle.springAnnotation.bean.Color;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

// 要实现 ImportBeanDefinitionRegistrar 接口
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * @param importingClassMetadata : 当前类的注解信息
     * @param registry               : bean定义的注册类
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 传入要定义bean的class对象
        RootBeanDefinition definition = new RootBeanDefinition(Color.class);

        // 传入bean名字,definition对象
        registry.registerBeanDefinition("color", definition);
    }
}

编写配置类

package com.miracle.springAnnotation.config;


import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@ComponentScan(value = "com.miracle")
@Import({MyImportBeanDefinitionRegistrar.class})  //导入beanDefinitionRegistrar
public class MainConfig4 {


}

第四种方式:
编写工厂 ColorFactoryBean.java

package com.miracle.springAnnotation.config;

import com.miracle.springAnnotation.bean.Color;
import org.springframework.beans.factory.FactoryBean;

// 创建一个spring定义的FactoryBean                     这里指定要创建什么类型的对象
public class ColorFactoryBean implements FactoryBean<Color> {

    // 工厂调用getObject方法,创建对象Color对象,这个对象会添加到容器中
    @Override
    public Color getObject() throws Exception {
        return new Color();
    }

    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }

    // 控制是否单例
    @Override
    public boolean isSingleton() {
        return false;
    }
}

编写配置类

package com.miracle.springAnnotation.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value = "com.miracle")
public class MainConfig5 {

    @Bean  // 这里创建了一个id为colorFactoryBean的bean,但是这个bean的类型是ColorFactoryBean实现的接口里面的泛型
    public ColorFactoryBean colorFactoryBean() {
        return new ColorFactoryBean();
    }
}

使用bean

// 这里直接拿工厂的名字,拿出来的就接口泛型里面的类型
Object obj = applicationContext.getBean("colorFactoryBean");
System.out.println("bean的类型:" + obj.getClass());
(4)指定bean的初始化和销毁方法

方式一

创建配置类 MainConfigOfLifeCycle.java

package com.miracle.springAnnotation.config;

import com.miracle.springAnnotation.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * bean的生命周期:bean创建---初始化---销毁的过程
 *
 * 容器管理bean的生命周期:
 *      我们可以自定义初始化和销毁方法:容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
 * 指定初始化和销毁方法: 指定 init-method 和 destroy-method 方法
 */
@Configuration
public class MainConfigOfLifeCycle {
    // 通过@Bean注解里面写 initMethod,destroyMethod 的值来指定初始化方法和销毁方法
    @Bean(initMethod = "init", destroyMethod = "detory")
    public Car car() {
        return new Car();
    }
}

定义bean

package com.miracle.springAnnotation.bean;

public class Car {

    public Car() {
        System.out.println("car constructor...");
    }
    // 定义bean的初始化方法
    public void init() {
        System.out.println("car ... init...");
    }
    // 定义bean的销毁方法
    public void detory() {
        System.out.println("car ... detory...");
    }
}

方式二:通过让Bean实现接口InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑)

创建配置类 MainConfig6.java

package com.miracle.springAnnotation.config;

import com.miracle.springAnnotation.bean.Cat;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig6 {

    @Bean
    public Cat cat() {
        return new Cat();
    }
}

定义bean

package com.miracle.springAnnotation.bean;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Cat implements InitializingBean, DisposableBean {

    public Cat() {
        System.out.println("cat constructor");
    }

    // 实现销毁方法
    @Override
    public void destroy() throws Exception {
        System.out.println("cat...destroy");
    }

    // 实现初始化方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("cat...init");
    }
}

方式三:可以使用JSR250规范提供的两个注解
@PostConstruct 在bean创建完成并且属性赋值完成,来执行初始化方法
@PreDestroy 在容器销毁bean之前通知我们进行清理工作

创建配置类 MainConfig7.java

package com.miracle.springAnnotation.config;

import com.miracle.springAnnotation.bean.Dog;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig7 {

    @Bean
    public Dog dog() {
        return new Dog();
    }
}

创建bean

package com.miracle.springAnnotation.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class Dog {

    public Dog() {
        System.out.println("dog constructor");
    }

    // 只需要在初始化方法上添加注解@PostConstruct,那么spring就会在对象创建并赋值之后调用
    @PostConstruct
    public void init() {
        System.out.println("Dog....@PostConstruct...");
    }

    // 只需要在初始化方法上添加注解@PreDestroy,那么spring就会在容器移除对象之前调用
    @PreDestroy
    public void detory() {
        System.out.println("Dog....@PreDestroy...");
    }
}

方式四:
使用spring提供的BeanPostProcessor(bean的后置处理器)

BeanPostProcessor接口说明,bean的后置处理器定义后会在spring创建每个bean对象的过程中都执行处理器中的方法

包含两个方法
// 在所有初始化方法调用之前执行
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

// 在所有初始化方法调用之后执行
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

编写配置文件
MainConfig8.java

package com.miracle.springAnnotation.config;


import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value = "com.miracle") // 扫描到自定义的BeanPostProcessor
public class MainConfig8 {

}

编写自定义BeanPostProcessor

package com.miracle.springAnnotation.config;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 *  定义自己的 后置处理器 : 初始化前后进行处理工作
 */
@Component  // 要使我们自定义的处理器工作,需要把这个类注册到springIOC容器中
public class MyBeanPostProcessor implements BeanPostProcessor {
    // 参数 bean 是容器帮我创建的bean
    // 参数 beanName 是bean的名字
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);
        // 返回值 是 返回将要用的bean实例,可以原封不动的返回bean,也可以返回包装过的bean,但是这里不能返回null,查看源代码发现,如果返回null,那么后面的BeanPostProcessor都不会执行了
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);
        return bean;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值