Java学习之Spring核心机制IoC和AOP

Java学习之Spring核心机制IoC和AOP,第1张

Java学习之Spring IoC和AOP

1 IoC

常规情况下,对象都是开发者手动创建的,使用IoC开发者不再需要创建对象,而是由IoC容器根据需求自动创建项目所需的对象。IoC(Inverse of Control:控制反转) 是一种设计思想,而不是一个具体的技术实现。IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。不过, IoC 并非 Spring 特有,在其他语言中也有应用。

1.1 不适用IoC创建对象

举个例子,现在有一个DataConfig类:

@Data
public class DataConfig {
    private String url;
    private String driverName;
    private String username;
    private String password;
}

如果需要实例化一个DataConfig对象并为其赋值,传统的做法像下面这样,需要由开发者自己创建对象并逐一赋值。

// 不用IoC手动创建对象
DataConfig dataConfig = new DataConfig();
dataConfig.setDriverName("Driver");
dataConfig.setUrl("localhost:8080/index");
dataConfig.setUsername("admin");
dataConfig.setPassword("123456");
1.2 基于xml和注解生成对象

Spring 时代我们一般通过 XML 文件来配置 Bean,后来开发人员觉得 XML 文件来配置不太好,于是 SpringBoot 注解配置就慢慢开始流行起来。

1.2.1 基于xml的IoC

开发者把需要的对象在xml文件中进行配置,Spring框架读取这个xml文件,根据配置文件的内容来创建对象。仍然沿用上面的例子,使用xml文件配置DataConfig,在resources文件夹下创建一个spring.xml文件(说明 xml文件的头是必须的):


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean class="javaGuide.IoC.DataConfig" id="config" >
        <property name="driverName" value="Driver">property>
        <property name="url" value="localhost:8080/index">property>
    bean>
beans>

然后编写java代码根据上面的配置文件创建对象:

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
System.out.println(context.getBean("config"));

执行结果:

DataConfig(url=localhost:8080/index, driverName=Driver, username=null, password=null)
1.2.2 基于注解的IoC

基于注解的IoC有两种:基于配置类和扫包+注解的方式。

1.2.2.1 基于配置类

首先创建一个配置类:

@Configuration
public class BeanConfiguration {
    @Bean(value = "config")
    public DataConfig dataConfig() {
        DataConfig dataConfig = new DataConfig();
        dataConfig.setDriverName("Driver");
        dataConfig.setUrl("localhost:8080/index");
        dataConfig.setUsername("admin");
        dataConfig.setPassword("123456");
        return dataConfig;
    }
}

然后调用即可。

ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfiguration.class);
System.out.println(context.getBean(DataConfig.class));
// 或者System.out.println(context.getBean("config"));

如果一个项目里面有多个配置类,可以在AnnotationConfigApplicationContext中传入包名,直接扫描该包下的所有配置类:

// 传入包名
ApplicationContext context = new AnnotationConfigApplicationContext("javaGuide.IoC");
System.out.println(context.getBean("config"));
1.2.2.2 扫包+注解

前面的方式还有有点复杂,扫包+注解是更为简单的一种方式:直接将Bean的创建交给目标类,在目标类添加@Component注解告诉spring框架被注解的类需要被注入到IoC的。
直接给DataConfig类加一个注解:

@Data
@Component
public class DataConfig {
    private String url;
    private String driverName;
    private String username;
    private String password;
}

然后调用:

ApplicationContext context = new AnnotationConfigApplicationContext("javaGuide.IoC");
System.out.println(context.getBean(DataConfig.class));
// 执行结果:DataConfig(url=null, driverName=null, username=null, password=null)

如果需要给对象中的属性赋值,可以使用@Value注解:

@Data
@Component
public class DataConfig {
    @Value("localhost:8080")
    private String url;

    @Value("Driver")
    private String driverName;

    @Value("user")
    private String username;
    
    @Value("123456")
    private String password;
}

1.3 依赖注入

举个例子:
假如除了DataConfig类之外,还有一个GlobalConfig类,其定义为:

@Data
@Component
public class GlobalConfig {
    @Value("3306")
    private String port;

    @Value("/")
    private String path;

    private DataConfig dataConfig;
}

如果也想通过IoC将DataConfig注入GlobalConfig呢?需要使用@Autowire注解:

@Data
@Component
public class GlobalConfig {
    @Value("3306")
    private String port;

    @Value("/")
    private String path;

    @Autowired
    private DataConfig dataConfig;
}

执行结果:

ApplicationContext context = new AnnotationConfigApplicationContext("javaGuide.IoC");
System.out.println(context.getBean(GlobalConfig.class));
// 执行结果:GlobalConfig(port=3306, path=/, dataConfig=DataConfig(url=localhost:8080, driverName=Driver, username=user, password=123456))
1.3.1 Autowire注解

@Autowired默认按类型装配(即通过类注入),默认情况下必须要求依赖对象存在,如果要允许null值,可以设置它的required属性为false。如果想使用名称装配可以结合@Qualifier注解进行使用。仍然以上面的例子说明一下:

首先给DataConfig的@Component注解一个名称config

@Data
@Component("config")
public class DataConfig {
    @Value("localhost:8080")
    private String url;

    @Value("Driver")
    private String driverName;

    @Value("user")
    private String username;

    @Value("123456")
    private String password;
}

然后设置GlobalConfig中的@Autowire

@Data
@Component
public class GlobalConfig {
    @Value("3306")
    private String port;

    @Value("/")
    private String path;

    @Autowired
    @Qualifier("config")
    private DataConfig dataConfig;
}

再调用即可:

ApplicationContext context = new AnnotationConfigApplicationContext("javaGuide.IoC");
System.out.println(context.getBean(GlobalConfig.class));
// 运行结果:GlobalConfig(port=3306, path=/, dataConfig=DataConfig(url=localhost:8080, driverName=Driver, username=user, password=123456))
2 AOP

AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

推荐教程:

  • 【2022版】2小时学会Spring核心机制IoC和AOP
  • SpringBoot中的AOP使用
推荐资料

JavaGuide中IoC和AOP相关的内容

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/883637.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-14
下一篇 2022-05-14

发表评论

登录后才能评论

评论列表(0条)

保存