IOC是Spring全家桶各个功能模块的基础,创建对象的容器。
AOP也是以IOC为基础,AOP是面向切面编程,抽象化的面向对象。
IOC
控制反转,将对象的创建进行反转,常规情况下,对象都是开发者手动创建的,使用IOC开发不再需要创建对象,而是由IOC容器根据要求自动创建项目所需要的对象。
第一种:注解实现IOC
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!--第一种:注解实现IOC-->
<bean class="com.gao.ioc.DataConfig" id="config">
<property name="url" value="http://localhost:8080"></property>
<property name="driverName" value="Driver"></property>
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
</bean>
</beans>
第二种:配置类实现IOC
package com.gao.config;
import com.gao.ioc.DataConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//第二种:配置类实现IOC
@Configuration
public class BeanConfiguration {
@Bean(value = "config")//如果注册的bean设置了value值,则根据这个值去查找
public DataConfig dataConfig(){
DataConfig dataConfig = new DataConfig();
dataConfig.setUrl("http://localhost:8080");
dataConfig.setDriverName("Driver");
dataConfig.setUsername("root");
dataConfig.setPassword("1234");
return dataConfig;
}
}
第三种:扫包+注解
package com.gao.ioc;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//第三种:扫包+注解
//在测试类中扫包
@Data
@Component//注解
public class DataConfig {
@Value("8080")
private String url;
@Value("Driver")
private String driverName;
@Value("root")
private String username;
@Value("1234")
private String password;
}
测试类:
package com.gao.ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
// ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// System.out.println(context.getBean("config"));
// ApplicationContext context = new AnnotationConfigApplicationContext("com.gao.config");
// System.out.println(context.getBean("config"));
ApplicationContext context = new AnnotationConfigApplicationContext("com.gao.ioc");//扫包
System.out.println(context.getBean(DataConfig.class));
}
}
AOP
面向切面编程,是一种抽象化的面向切面编程,对面向对象编程的一种补充。
应用:打印日志
计算器方法中,日志和业务混合在一起,AOP要做的就是将日志和业务代码全部抽象出去统一进行处理,计算器方法中只保留核心的业务代码。
做到核心业务与非业务代码的解耦合。
aopapplication.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://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.xsd">
<!--扫描包-->
<context:component-scan base-package="com.gao.aop"></context:component-scan>
<!--开启自动生成代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
接口类:
package com.gao.aop;
public interface Cal {
int add(int num1,int num2);
int sub(int num1,int num2);
int mul(int num1,int num2);
int div(int num1,int num2);
}
实现类:
package com.gao.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;
}
}
切面类:
package com.gao.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(int com.gao.aop.CalImpl.*(..))")
public void before(JoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法的参数是:"+ Arrays.toString(joinPoint.getArgs()));
}
@AfterReturning(value = "execution(int com.gao.aop.CalImpl.*(..))",returning = "result")
public void afterreturning(JoinPoint joinPoint,Object result){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法的结果是:"+ result);
}
}
测试类:
package com.gao.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("aopapplication.xml");
Cal bean = context.getBean(Cal.class);
System.out.println(bean.add(7, 5));
System.out.println(bean.sub(7, 5));
System.out.println(bean.mul(7, 5));
System.out.println(bean.div(7, 5));
}
}
一个切面类只能被一个实现类使用!
如果有多个实现类,并且都用了@Component注解,那么运行时会报错!