1.spring 不会自动去寻找注解,必须告诉 spring 哪些包下的类中可能有注解;使用注解来取代配置文件.
1.1 引入xmlns:context ,指定扫描范围
<context:component-scan base-package="com.advice,com.test"></context:component-scan>
1.3 @Component
1.4 相当于<bean/>
1.5 如果没有参数,把类名首字母变小写,相当于<bean id=”别名”/>
1.6 @Component(“自定义名称”)
1.7 <aop:aspectj-autoproxy proxy-target-class="true"> </aop:aspectj-autoproxy>
<!--proxy-target-class="true"使用cglib动态代理;
否则使用jdk动态代理-->
1.8 实现步骤:
2.1 在spring 配置文件中设置注解在哪些包中 ,多个文件夹用分号隔开 ;以及加入属性:" xmlns:context"" xsi:schemaLocation"
<?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:context="http://www.springframework.org/schema/context"
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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.advice,com.test"></context:component-scan> <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> <!--proxy-target-class="true"使用cglib动态代理; 否则使用jdk动态代理--> </beans>
2.2在Demo 类中添加@Componet
2.2.1在方法上添加@Pointcut(“”) 定义切点
import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Component public class demo { @Pointcut("execution(* com.test.demo.demo1())") public void demo1(){ // int i=5/0; System.out.println("demo1"); } }
2.3在通知类中配置 --@Component @Aspect 都不能剩下!!
2.3.1@Component 类被spring 管理
@Aspect 相当于<aop:aspect/>表示通知方法在当前类中;
package com.advice; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component @Aspect public class MyAdvice { @Before("com.test.demo.demo1()") public void mybefore(){ System.out.println("前置通知!!"); } @After("com.test.demo.demo1()") public void myafter(){ System.out.println("后置通知"); } @AfterThrowing("com.test.demo.demo1()") public void mythrow(){ System.out.println("异常通知"); } @Around("com.test.demo.demo1()") public Object myArround(ProceedingJoinPoint p) throws Throwable { System.out.println("环绕-前置"); Object result = p.proceed(); System.out.println("环绕-后置"); return result; } }
2.4 编写test测试类并进行测试
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class test { public static void main(String[] args) { ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); // 输出Spring自动加载的所有类 // String[] names = ac.getBeanDefinitionNames(); // for(int i=0;i< names.length;i++) // System.out.println(names[i]); demo d=ac.getBean("demo",demo.class); d.demo1(); } }
myAdvice demo org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.aop.config.internalAutoProxyCreator org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor 环绕-前置 前置通知!! demo1 环绕-后置 后置通知
八.代理设计模式
1.设计模式:前人总结的一套解决特定问题的代码.
2.代理设计模式优点:
2.1保护真实对象
2.2让真实对象职责更明确.
2.3扩展
3.代理设计模式
3.1真实对象.(老总)
3.2代理对象(秘书)
1.抽象对象(抽象功能),谈小目标
九. 静态代理设计模式
2.由代理对象代理所有真实对象的功能.
2.1自己编写代理类
2.2每个代理的功能需要单独编写
3.静态代理设计模式的缺点:
1.当代理功能比较多时,代理类中方法需要写很多.
十. 动态代理
2.为了解决静态代理频繁编写代理功能缺点.
3.分类:
3.1JDK 提供的cglib 动态代理
十一. JDK 动态代理
1.和cglib 动态代理对比
1.1优点:jdk 自带,不需要额外导入jar
1.2缺点:
1.2.1真实对象必须实现接口
1.2.2利用反射机制.效率不高.
2.使用JDK 动态代理时可能出现异常ClasscastException : cat not cast to xxx.
出现原因:希望把接口对象转换为具体真实对象
十二: cglib 动态代理
1.cglib 优点:
1.1基于字节码,生成真实对象的子类.
1.1.1运行效率高于JDK 动态代理.
1.2不需要实现接口
2.cglib 缺点:
2.1非JDK 功能,需要额外导入jar
3.使用spring aop 时,只要出现Proxy 和真实对象转换异常
3.1设置为true 使用cglib
3.2设置为false 使用jdk(默认值)
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>