1.笔记
* 使用AOP时最后只用一种方式 Annotation
* AOP Aspect(切面) Oriented Programming 面向切面编程
* 代理模式:不改变原有的类情况下,增强原有类方法的功能。方法执行之前和方法执行之后加些东西
* AOP 和 OOP(Object Oriented Programming) 的关系
相辅相成
* 从一段话开始入门:
在一个服务的流程中插入与业务逻辑无关的系统服务逻辑(例如:Logging、Security),这样的逻辑称为Cross-cutting concerns,将Cross-cutting concerns(横切面)独立出来设计为一个对象,这样的特殊对象称之为Aspect(切面),Aspect-oriented programming着重在Aspect的设计和应用程序的织入(Weave)上
* 切面Aspect:就是除业务逻辑之外的逻辑
*** 但凡问框架原理:都问的是基于模式或思维怎么做的
struts MVC Hibernate ORM Spring IOC AOP
* 切点(pointcut):要想找一个切入点找的是包 ->类 ->方法
切点表达式pointcut = "execution(* 包名.*(..) )" *:任意返回值 execution:执行
切面:要切入的内容
织入: 把切面放到切点上执行就是织入
通知:横切面分开单个叫通知
* AOP的实现种类
第一种:实现Spring API的传统模式:侵入式实现,已淘汰(spring推崇无侵入式编程)
第二种:基于XML的设置
第三种:使用Annotation配置
* 切入种类
1.Before Advice方法之前,
2.After Returning Advice之后切入,
3.After Throwing Advice异常后切,
4.Around Advice环绕切
* 实现步骤(以方法之前切入为例)
* 编写被切入类DeptDAO
* 编写通知类
* 配置文件中引入AOP标签的schema
* AOP配置
* spring内部已经植入可cglib代理
* AOP是基于代理模式来进行实现的
2.需要的jar包
下面是AOP原理
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<!-- 启用annotation注入 -->
<context:annotation-config/>
</beans>
spring-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<bean id="deptdao" class="com.anbo.dao.DeptDAO"></bean>
</beans>
DeptDAO.java
package com.anbo.dao;
import org.springframework.cglib.proxy.Enhancer;
public class DeptDAO {
public void save(){
// System.out.println("logging: start , time is = "+new Date());//系统服务逻辑
System.out.println("save dept...");//业务逻辑
// System.out.println("logging: end , time is ="+new Date());//系统服务逻辑
}
}
BeforeAOP.java
package com.anbo.aop;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
public class BeforeAOP {
public void before1(JoinPoint jp){//JoinPoint jp:切入点这个必须有 这个获取切入类的信息
System.out.println("logging: start , time is = "+new Date()+jp.getTarget().getClass());//系统服务逻辑
}
public void before2(){//JoinPoint jp:切入点这个必须有 这个获取切入类的信息
System.out.println("logging: start2 , time is = "+new Date());//系统服务逻辑
}
}
AfterAOP.java
package com.anbo.aop;
import java.util.Date;
public class AfterAOP {
public void after(){
System.out.println("logging: end , time is ="+new Date());//系统服务逻辑
}
}
spring-aop.java
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<!-- 切面 通知类 -->
<bean id="beforeaop" class="com.anbo.aop.BeforeAOP"></bean>
<bean id="afteraop" class="com.anbo.aop.AfterAOP"></bean>
<!-- 配置切入 -->
<!-- 下面这个xml配置方式 -->
<!-- 还有三种切入,下面是方法之前切入,其余三种自己搜着学差不多 -->
<aop:config>
<aop:aspect id="before" ref="beforeaop">
<aop:before method="before1"
pointcut="execution(* com.anbo.dao.DeptDAO.*(..))"/>
<!-- execution 执行 *:任意返回值 .*:类的所有方法 (..)方法的参数 -->
<aop:before method="before2"
pointcut="execution(* com.anbo.dao.DeptDAO.*(..))"/>
</aop:aspect>
<aop:aspect id="after" ref="afteraop">
<aop:after method="after"
pointcut="execution(* com.anbo.dao.DeptDAO.*(..))"/>
</aop:aspect>
</aop:config>
</beans>
TestDept.java
package com.anbo.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.anbo.dao.DeptDAO;
public class TestDept {
public static void main(String[] args) {
//通配符 什么都能代表 正则表达式 以spring开头的所有配置文件全部 加载
//struts.xml
ApplicationContext context = new ClassPathXmlApplicationContext("spring*.xml");
DeptDAO dao = (DeptDAO)context.getBean("deptdao");
System.out.println(dao);
dao.save();
}
}
--------------------------------------------------下面是注解方式--------------------------------------------------
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<!-- 启用annotation注入 -->
<context:annotation-config/>
</beans>
spring-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<bean id="deptdao" class="com.anbo.dao.DeptDAO"></bean>
</beans>
AfterReturnAdvice.java
package com.anbo.aop;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AfterReturnAdvice {
@AfterReturning("execution(* com.anbo.dao.DeptDAO.*(..))")
public void after(JoinPoint jp){
System.out.println("logging:after......"+new Date());
}
}
BeforeAdvice.java
package com.anbo.aop;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class BeforeAdvice {
//告诉方法在哪个地方执行
@Before("execution(* com.anbo.dao.DeptDAO.*(..))")
public void before (JoinPoint jp){
System.out.println("logging :: start"+jp.getTarget().getClass() + "start" + new Date());
}
}
DeptDAO.java
package com.anbo.dao;
public class DeptDAO {
public void save(){
// System.out.println("logging: start , time is = "+new Date());//系统服务逻辑
System.out.println("save dept...");//业务逻辑
// System.out.println("logging: end , time is ="+new Date());//系统服务逻辑
}
}
spring-aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<!-- aop是基于代理完成的.. -->
<aop:aspectj-autoproxy />
<!-- 配置切面类 -->
<!-- <bean id="beforeadvice" class="com.anbo.aop.BeforeAdvice"></bean> -->
<bean class="com.anbo.aop.BeforeAdvice"></bean>
<!-- 返回值之后切面 -->
<bean class="com.anbo.aop.AfterReturnAdvice"></bean>
</beans>
package com.anbo.dao;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
//这里想测谁就注入谁
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring*.xml"})
public class TestDeptDAO {
@Resource
private DeptDAO deptdao;
@Test
public void save(){
/*ApplicationContext context = new ClassPathXmlApplicationContext("spring*.xml");
DeptDAO dao = (DeptDAO)context.getBean("deptdao");
dao.save();*/
deptdao.save();
}
}