一:SpringIOC
IOC(中文释义:控制反转),主要作用于解耦。IOC是指将创建对象的控制权交给spring框架进行管理,spring框架根据配置文件或注解等方式,创建bean对象并管理各个bean对象之家的依赖关系,使对象之间形成耦合松散的状态,实现解耦。
控制:指的是对象创建(实例化、管理)的权力
反转:控制权交给外部环境(spring框架、IOC容器)
IOC的使用:
(1)导入坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.27</version>
</dependency>
(2)将需要已解耦创建的对象,类注入springIOC容器
<bean id="类的唯一标识" class="注入的类"></bean>
<?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">
<bean id="StudentDaoImpl" class="com.apesource.dao.StudentDaoImpl"></bean>
<bean id="StudentserviceImpl" class="com.apesource.service.StudentserviceImpl"/>
<bean id="Date" class="java.util.Date"> </bean>
</beans>
(3)向springIOC容器索取实例
package com.apesource.test;
import com.apesource.dao.IStudentDao;
import com.apesource.service.IStudentservice;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Date;
public class Test {
public static void main(String[] args){
ApplicationContext context =new ClassPathXmlApplicationContext("beans.xml");
IStudentDao dao=(IStudentDao) context.getBean("StudentDaoImpl");
IStudentservice service =(IStudentservice) context.getBean("StudentserviceImpl");
Date date=(Date) context.getBean("Date");
System.out.println(date);
service.save();
dao.save();
}
}
二:SpringDI(依赖注入)
DI(依赖注入) 是对IOC概念的不同角度的描述,是指应用程序在运行时,每一个bean对象都依赖IOC容器注入当前bean对象所需要的另外一个bean对象。
1.DI的使用:
(1)提供set方法(或者构造方法)
package com.apesource.Controller;
import com.apesource.service.StudentServiceImpl;
public class StudentControllerImpl implements IStudentController{
StudentServiceImpl service;
public void setService(StudentServiceImpl service) {
this.service = service;
}
@Override
public void save() {
System.out.println("controller的新增");
service.save();
}
}
(2)配置标签
语法:<property name="属性名" ref="关联的id"></property>
位置:<bean>此位置</bean>
<bean id="StudentControllerImpl" class="com.apesource.Controller.StudentControllerImpl">
<property name="service" ref="StudentServiceImpl"></property>
</bean>
2.DI注入方式
A.set注入
B.构造注入
构造注入即为将set方法改为构造方法即可。
3.DI注入数据类型
A.基本类型与String
B.javaBean对象
C.复杂类型
复杂类型包括:list、set、String[]、map、properties
<?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">
<bean id="StudentControllerImpl" class="com.apesource.Controller.StudentControllerImpl">
<property name="service" ref="StudentServiceImpl"></property>
</bean>
<bean id="student" class="com.apesource.bean.Student">
<property name="name" value="蜡笔小新"></property>
<property name="age" value="10"></property>
<property name="hobby" value="玩玩具"></property>
</bean>
<bean id="teacher" class="com.apesource.bean.Teacher">
<property name="list">
<list>
<value>哪吒2</value>
<value>唐探</value>
<value>熊出没重启未来</value>
<value>封神2</value>
<value>射雕英雄传</value>
</list>
</property>
<property name="set">
<set>
<value>西安</value>
<value>宝鸡</value>
<value>郑州</value>
<value>兴平</value>
<value>延安</value>
</set>
</property>
</bean>
</beans>
三SpringAOP
AOP(Aspect-Oriented Programming: 面向切面编程):将那些与业务无关,却为业务模块所共同调用的逻辑(例如事务处理、日志管理、权限控制等)封装抽取成一个可重用的模块,这个模块被命名为“切面”(Aspect),便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性;
Spring AOP 基于动态代理实现:
○ 如果被代理的对象,已经实现某个接口,则 Spring AOP 会使用 JDK Proxy(反射),基于接口的方式,创建代理对象(JDK动态代理的核心是InvocationHandler接口和Proxy类);
○ 如果被代理的对象,没有实现某个接口,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib,基于继承的方式,生成一个被代理对象的子类来作为代理(Cglib动态代理的核心是MethodInterceptor接口和Enhancer类);
(1)AOP的通知类型
AOP将抽取出来的共性功能称为通知;通知类型:以通知在上下文中的具体位置作为划分
前置通知(Before)
后置通知(After)
返回通知(After-returning)
异常通知(After-throwing)
环绕通知(Around)
(2)AOP连接点(Join point)
AOP将所有的方法都视为连接点,不管是接口里面的抽象方法,还是实现类里面的重写方法,都是连接点。
AOP切点(Pointcut)
AOP将可能被抽取共性功能的方法称为切入点。切入点是连接点的子集
AOP目标对象(Target): 就是挖掉功能的方法对应的类生的对象,这种对象是无法直接完成最终工作的。
AOP织入(Weaving):就是将挖掉的功能回填的动态过程
(3)AOP切面:切点+通知
1.添加依赖,aop与aspectj表达式的依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
2.创建spring的主配置文件,bean内的命名空间要添加aop的
3.创建业务代码并编写日志记录代码(事务管理代码)
4.将业务层与日志记录层注入spring容器
5.<aop:config>--aop配置
aop:aspect--aop切面
aop:before--通知内容与通知类型
切点表达式配置语法:
execution(修饰符 返回值 包名称.类名称.方法名称(参数列表))
eg:
execution(public void com.apesource.service.ServiceImp.findAll())
1.修饰符可以省略代表任意
execution(返回值 包名称.类名称.方法名称(参数列表))
2.返回值可以使用“*”代表任意
execution(* 包名称.类名称.方法名称(参数列表))
3.包名可以使用“*”代表任意名称
execution(* *.*.*.类名称.方法名称(参数列表))
4.包名可以使用“..”代表任意个数
execution(* *...类名称.方法名称(参数列表))
5.类名与方法名可以使用“*”代表任意
execution(* *...*.*(参数列表))
6.参数列表可以使用".."代表任意个数任意类型
execution(* *...*.*(..))
如果有参数
int======>int
String===>java.lang.String
<?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: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/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="service" class="com.apesource.service.CountServiceImpl"></bean>
<bean id="logger" class="com.apesource.util.Logger"></bean>
<!--配置Aop-->
<aop:config>
<!--配置切面-->
<aop:aspect id="aopAspect" ref="logger">
<!--配置切点-->
<aop:pointcut id="pointCut" expression="execution(* com.apesource.service.*.*(..))"></aop:pointcut>
<!-- <!–前置通知–>-->
<!-- <aop:before method="beforeLogger" pointcut-ref="pointCut"></aop:before>-->
<!-- <!–返回通知–>-->
<!-- <aop:after-returning method="returnLogger" pointcut-ref="pointCut"></aop:after-returning>-->
<!-- <!–异常通知–>-->
<!-- <aop:after-throwing method="throwLogger" pointcut-ref="pointCut"></aop:after-throwing>-->
<!-- <!–后置通知–>-->
<!-- <aop:after method="afterLogger" pointcut-ref="pointCut"></aop:after>-->
<aop:around method="aroundLogger" pointcut-ref="pointCut"></aop:around>
</aop:aspect>
</aop:config>
</beans>
package com.apesource.util;
import org.aspectj.lang.ProceedingJoinPoint;
public class Logger {
public void beforeLogger(){
System.out.println("日志类logger中调用前置通知进行日志记录");
}
public void returnLogger(){
System.out.println("日志类logger中调用返回通知进行日志记录");
}
public void throwLogger(){
System.out.println("日志类logger中调用异常通知进行日志记录");
}
public void afterLogger(){
System.out.println("日志类logger中调用后置通知进行日志记录");
}
public Object aroundLogger(ProceedingJoinPoint pjp){
Object obj = null;
try {
System.out.println("环绕通知的前置通知");
obj =pjp.proceed(pjp.getArgs());
System.out.println("环绕通知的返回通知");
} catch (Throwable e) {
e.printStackTrace();
System.out.println("环绕通知的异常通知");
}finally {
System.out.println("环绕通知的后置通知");
}
return obj;
}
}