AOP以及交互扩展
AOP:
AOP为Aspect Oriented Programming
面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
AOP是OOP的延续,是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
利用AOP可以对业务逻辑的各个部分进行隔离,
从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
AOP核心概念
横切关注点
对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点
切面(aspect)
类是对物体特征的抽象,切面就是对横切关注点的抽象
连接点(joinpoint)
被拦截到的点,Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器
切入点(pointcut)
对连接点进行拦截的定义
通知(advice)
所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类
目标对象
代理的目标对象
织入(weave)
将切面应用到目标对象并导致代理对象创建的过程
AOP案例一
步骤一:
导入所需的依赖
步骤二:
创建实体类
public class Student { private Integer stuid; private String stuName; public Integer getStuid() { return stuid; } public void setStuid(Integer stuid) { this.stuid = stuid; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } }
步骤三:
创建DAO
public interface IStudent { public int addStu(Student stu); }
步骤四:
创建DAOimpl
public class IStudentimpl implements IStudent { @Override public int addStu(Student stu) { System.out.println("Dao添加Student成功!!!"); return 0; } }
步骤五:
创建Service
public interface IStudentservice { public int addStu(Student stu); }
步骤六:
创建Serviceimpl
public class IStudentserviceimpl implements IStudentservice { private IStudent student; public IStudent getStu() { return student; } public void setStu(IStudent student) { this.student = student; } @Override public int addStu(Student stu) { int i = student.addStu(stu); return i; } }
步骤七:
创建增强类
public class MyAdvice implements MethodBeforeAdvice, AfterReturningAdvice{ @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { System.out.println("我是前增强"); } @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("我是后增强"); } }
步骤八:
创建大配置文件
<?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" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--注入bean id相当于当前bean唯一标识 class是bean 的全路径 property注入bean中的属性 必须封装 --> <!--声明Dao--> <bean id="iStudent" class="com.SpringMckz.Dao.impl.IStudentimpl"></bean> <!--Service--> <bean id="iStudentservice" class="com.SpringMckz.Service.impl.IStudentserviceimpl"> <property name="stu" ref="iStudent"></property> </bean> <!--声明增强类--> <bean id="stus" class="com.SpringMckz.advice.MyAdvice"></bean> <!--增强处理--> <aop:config> <!--切点 对那个方法增强--> <aop:pointcut id="pointcut" expression="execution(* *..Service.*.*(..))"/> <!--切面--><aop:advisor advice-ref="stus" pointcut-ref="pointcut"></aop:advisor> </aop:config> </beans>
步骤九:
测试
@Test public void teststu(){ ApplicationContext atc=new ClassPathXmlApplicationContext("applicationContext.xml"); IStudentservice sss = (IStudentservice)atc.getBean("iStudentservice"); sss.addStu(new Student()); }
AOP案例二
自己设置增强方法
增强类
public class MyAdvice2 { public void qianZeng(){ System.out.println("嘿嘿,我在前"); } public void houZeng(){ System.out.println("嘿嘿,我在后"); } }
更改大配置文件
<?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" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--注入bean id相当于当前bean唯一标识 class是bean 的全路径 property注入bean中的属性 必须封装 --> <!--声明Dao--> <bean id="iStudent" class="com.SpringMckz.Dao.impl.IStudentimpl"></bean> <!--Service--> <bean id="iStudentservice" class="com.SpringMckz.Service.impl.IStudentserviceimpl"> <property name="stu" ref="iStudent"></property> </bean> <!--声明增强类--> <bean id="stus" class="com.SpringMckz.advice.MyAdvice2"></bean> <!--增强处理--> <aop:config> <!--切点 对那个方法增强--> <aop:pointcut id="pointcut" expression="execution(* *..Service.*.*(..))"/> <!--切面--> <!--<aop:advisor advice-ref="stus" pointcut-ref="pointcut"></aop:advisor>--> <aop:aspect ref="stus"> <!--前--> <aop:before method="qianZeng" pointcut-ref="pointcut"></aop:before> <!--后--> <aop:after method="houZeng" pointcut-ref="pointcut"></aop:after> </aop:aspect> </aop:config> </beans>
测试
@Test public void teststu(){ ApplicationContext atc=new ClassPathXmlApplicationContext("applicationContext.xml"); IStudentservice sss = (IStudentservice)atc.getBean("iStudentservice"); sss.addStu(new Student()); }
三种注入方式
Spring通过DI(依赖注入)实现IOC(控制反转)
常用的注入方式主要有三种:构造方法注入,setter注入,P命名空间的注入。
步骤一:
创建实体类:
public class Teacher { private Integer tid; private String tname; @Override public String toString() { return "Teacher{" + "tid=" + tid + ", tname='" + tname + '\'' + '}'; } public Teacher(Integer tid, String tname) { this.tid = tid; this.tname = tname; } public Teacher() { } public Integer getTid() { return tid; } public void setTid(Integer tid) { this.tid = tid; } public String getTname() { return tname; } public void setTname(String tname) { this.tname = tname; } }
更改大配置文件
<?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" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--注入bean id相当于当前bean唯一标识 class是bean 的全路径 property注入bean中的属性 必须封装 --> <!--三种注入方式--> <!--setter注入--> <bean id="teacher" class="com.SpringMckz.di.Teacher"> <property name="tid" value="1"></property> <property name="tname" value="梅川酷子"></property> </bean> <!--构造注入--> <!--<bean id="teacher" class="com.SpringMckz.di.Teacher"> <constructor-arg value="18" type="java.lang.Integer" index="0"></constructor-arg> <constructor-arg value="梅川酷子" type="java.lang.String" index="1"></constructor-arg> </bean>--> <!--P命名空间注入--> <!--<bean id="teacher" class="com.SpringMckz.di.Teacher" p:tid="20" p:tname="梅川酷子"></bean>--> </beans>
测试
@Test public void teachertest(){ ApplicationContext atc=new ClassPathXmlApplicationContext("applicationContext.xml"); Teacher sss = (Teacher)atc.getBean("teacher"); System.out.println(sss.toString()); }