.Net转Java自学之路—Spring框架篇二(IOC注解、AOP)
Spring的Bean操作(注解方式):
注解:代码中特殊的标记,使用注解可以完成相关功能。
@注解名称(属性名称=属性值)
注解可以使用在类、方法、属性上面。
主要用途:可以替代配置文件来创建对象和属性注入。
在做ioc基本功能时,配置文件引入的schema约束为beans约束,而在做spring的ioc注解开发,引入新schema约束的context约束。
<?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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> </beans>
引入约束后,注解方式还需要在配置文件中开启注解扫描:
<!-- 开启注解扫描:该配置扫描包中的类、方法、属性上是否有注解 --> <context:component-scan base-package="包名"></context:component-scan> <!-- 该配置只扫描属性上是否有注解 --> <context:annotation-config></context:annotation-config>
使用注解创建对象:在创建的类上方使用注解即可。
/** * 该注解中的value="test"相当于配置文件中的<bean id="test"...... */ @Component(value="test") public class Test{ }
创建对象含有四种注解方式:
四个注解的目前功能都是一样的。Spring种提供@Component的三个衍生注解:
@Controller:wen层 @Service:业务层 @Repository:持久层
该三种注解方式时为了让标注类本身的用途清晰。Spring后续版本会对其增强。
@Scope(Value="prototype"):多实例;作用范围。
@Component(value="test") @Scope(value="singleton")//单实例的 public class Test{ }
使用注解注入属性:
使用注解方式的属性注入时不需要set方法,而是在需要注入的属性上方使用注解@Autowired即可。
除去@Autowired注解外还有另一种注解方式:@Resource(name="指定注解类种的value值")
XML和注解方式混合使用:
创建对象操作使用配置文件方式实现。
注入属性的操作使用注解方式实现。
AOP:
面向切面编程。扩展功能不修改源代码实现。AOP采取横向抽取机制,取代了传统的纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)
aop操作相关术语:
Joinpoint(连接点):指那些被拦截到的点。在Spring中,这些点指的时方法,因为Spring只支持方法类型的连接点。
简述:指类中那些方法可以被增强,这些方法称为连接点。
Pointcut(切入点):指要对那些Joinpoint进行拦截的定义。
简述:指在类中可以有很多的方法被增强,实际增强的方法称为切入点。
Advice(通知/增强):增强的逻辑称为增强。所谓通知是指拦截到Joinpoint之后所要做的事情就是通知,通知分为:
前置通知:在方法之前执行。
后置通知:在方法之后执行。
异常通知:方法出现异常。
最终通知:在后置之后执行。
环绕通知(切面要完成的功能):在方法之前和之后执行。
Aspect(切面):是切入点和通知(引介)的结合。
简述:把增强应用到具体方法上,就是把增强用到切入点的过程称为切面。
Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下,Introduction可以在运行期为类动态的添加一些方法或Field。
Target(目标对象):代理的目标对象(要增强的类)。
Weaving(织入):是把增强应用到目标的过程。把advice应用到target的过程。
Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类。
Spring基于aspectj的xml方式的AOP操作:
在Spring中进行aop操作,需要使用aspectj来实现。aspectj是一个面向切面的框架,是一个基于Java语言的aop框架。
aspectj不是Spring的一部分,和Spring一起使用进行aop操作。Spring2.0之后新增了对aspectj支持。
使用aspectj来实现aop有两种方式:1、基于aspectj的XML配置。2、基于aspectj的注解方式。
AOP操作准备:
1、除去导入基本的jar包之外,还需要导入aop相关的jar包:
aopalliance.jar、aspectjweaver.jar、spring-aop.RELEASE.jar、spring-aspects.RELEASE.jar
2、创建Spring核心配置文件。需要导入aop约束。
<?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 http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans>
使用表达式配置切入点:
1、切入点:实际增强的方法。
2、常用表达式格式:execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
例:execution(* 增强方法的全路径(..)) *:任意的修饰符
execution(* cn.test.aop.Test.*(..)) 类.*:对类中的所有方法增强
execution(* *.*(..)) *.*:对所有类中的所有方法进行增强
execution(* save*(..)) save*:匹配所有save开头的方法进行增强
<!-- 配置对象 --> <bean id="test" class="Test全路径"></bean> <bean id="zqtest" class="ZQTest全路径"></bean> <!-- 配置aop操作 --> <aop:config> <!-- 配置切入点 --> <!-- 对Test类中所有方法进行增强 --> <aop:pointcut expression="execution(* Test全路径.*(..))" id="pc1"></aop:pointcut> <!-- 配置切面 --> <!-- 把增强用到方法上 --> <aop:aspect ref="zqtest"> <!-- 配置增强类型 method:增强类中使用那个方法作为前置执行 pointcut-ref:作用在那个切入点上, 对应配置切入点的id值--> <aop:before method="方法名" pointcut-ref="pc1"/> <!-- 后置执行 --> <aop:after-returning method="方法名" pointcut-ref="pc1"/> <!-- 环绕执行 在环绕方法中用 ProceedingJoinPoint.proceed() 来执行被增强的方法--> <aop:around method="环绕方法名" pointcut-ref="pc1"> </aop:aspect> </aop:config>
基于aspectj的注解aop操作:
使用注解方式实现aop操作:先创建对象,然后开启AOP操作。在增强类上使用注解完成aop操作;并在增强的方法上使用注解完成增强配置。
<!-- 配置对象 --> <bean id="test" class="Test全路径"></bean> <bean id="zqtest" class="ZQTest全路径"></bean> <!-- 开启aop操作 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Aspect public class ZQTest{ //在方法上使用注解完成增强配置 @Before(value="execution(* Test类全路径.*(..))") public void fun(){ } }