什么是IOC
控制反转,将对象的创建进行反转,常规情况下,对象都是开发者手动创建的,使用IOC开发者不再需要创建对象,而是由IOC容器根据需求自动创建项目所需要的对象。
相关依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.15</version>
</dependency>
案例:
随便创建一个实体类:
package org.example.pojo;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
public class DataConfig {
private String ip;
private String dataBaseName;
private String userName;
private String pwd;
}
不用IOC,所有对象开发者自己创建:
测试:
package org.example.test;
import org.example.pojo.DataConfig;
public class Test {
public static void main(String[] args) {
DataConfig dataConfig = new DataConfig();
dataConfig.setIp("127.0.0.1")
.setDataBaseName("test")
.setUserName("root")
.setPwd("ok");
System.out.println(dataConfig);
}
}
测试结果:
使用IOC,对象不用开发者创建,而是交给Spring框架来完成:
一、基于XML:
开发者把需要的对象在XML中进行配置,Spring框架读取这个配置文件,根据配置文件的内容来创建对象。
创建一个spring.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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<bean class="org.example.pojo.DataConfig" id="config">
<property name="ip" value="127.0.0.1" />
<property name="dataBaseName" value="test" />
<property name="userName" value="root" />
<property name="pwd" value="ok" />
</bean>
</beans>
测试:
package org.example.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
System.out.println(context.getBean("config"));
}
}
测试结果:
二、基于注解:
1、配置类
用一个Java类来替代XML文件,把在XML中配置的内容放到配置类中。
package org.example.configuration;
import org.example.pojo.DataConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeanConfiguration {
@Bean(value = "config")
public DataConfig dataConfig(){
DataConfig dataConfig = new DataConfig();
dataConfig.setIp("127.0.0.1")
.setDataBaseName("test")
.setUserName("root")
.setPwd("ok");
return dataConfig;
}
}
测试:
package org.example.test;
import org.example.configuration.BeanConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test3 {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfiguration.class);
System.out.println(context.getBean("config"));
}
}
测试结果:
2、扫包+注解
更简单的方式,不再需要依赖于XML或者配置类,而是直接将bean的创建交给目标类,在目标类添加注解来创建。
package org.example.pojo;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Data
@Component
@Accessors(chain = true)
public class DataConfig2 {
@Value("127.0.0.1")
private String ip;
@Value("test")
private String dataBaseName;
@Value("root")
private String userName;
@Value("ok")
private String pwd;
}
测试:
package org.example.test;
import org.example.pojo.DataConfig2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test4 {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext("org.example.pojo");
System.out.println(context.getBean(DataConfig2.class));
}
}
测试结果:
自动创建对象,完成依赖注入。
package org.example.pojo;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Data
@Component
public class GlobalConfig {
@Value("8080")
private String port;
@Value("/")
private String path;
@Autowired
private DataConfig2 dataConfig2;
}
测试:
package org.example.test;
import org.example.pojo.GlobalConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test5 {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext("org.example.pojo");
System.out.println(context.getBean(GlobalConfig.class));
}
}
测试结果:
@Autowired 通过类型进行注入,如果需要通过名称取值,通过 @Qualifier 注解完成名称的映射。
package org.example.pojo;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Data
@Component
public class GlobalConfig2 {
@Value("8080")
private String port;
@Value("/")
private String path;
@Autowired
@Qualifier("config")
private DataConfig2 dataConfig2;
}
测试:
package org.example.test;
import org.example.pojo.GlobalConfig2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test6 {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext("org.example.pojo");
System.out.println(context.getBean(GlobalConfig2.class));
}
}
测试结果:
什么是AOP
面向切面编程,是一种抽象化的面向对象编程,对面向对象编程的一种补充,底层使用动态代理机制来实现。
相关依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.18</version>
</dependency>
应用场景:
打印日志、事务、权限处理
案例:
1、创建切面类
package org.example.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@Aspect
public class LoggerAspect {
@Before("execution(public int org.example.aop.CalImpl.*(..))")
public void before(JoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法的参数是"+ Arrays.toString(joinPoint.getArgs()));
}
@AfterReturning(value = "execution(public int org.example.aop.CalImpl.*(..))",returning = "result")
public void afterReturning(JoinPoint joinPoint,Object result){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法的结果是"+result);
}
}
2、实现类添加 @Component 注解
package org.example.aop;
public interface Cal {
public int add(int num1, int num2);
public int sub(int num1, int num2);
public int mul(int num1, int num2);
public int div(int num1, int num2);
}
package org.example.aop;
import org.springframework.stereotype.Component;
@Component
public class CalImpl implements Cal {
@Override
public int add(int num1, int num2) {
int result = num1 + num2;
return result;
}
@Override
public int sub(int num1, int num2) {
int result = num1 - num2;
return result;
}
@Override
public int mul(int num1, int num2) {
int result = num1 * num2;
return result;
}
@Override
public int div(int num1, int num2) {
int result = num1 / num2;
return result;
}
}
3、配置自动扫包,开启自动生成代理对象
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 自动扫包 -->
<context:component-scan base-package="org.example.aop"></context:component-scan>
<!-- 开启自动生成代理 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
4、使用
package org.example.test;
import org.example.aop.Cal;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test7 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring2.xml");
Cal bean = context.getBean(Cal.class);
System.out.println(bean.add(9, 8));
System.out.println(bean.sub(9, 8));
System.out.println(bean.mul(9, 8));
System.out.println(bean.div(9, 8));
}
}
测试结果:
相关视频: