[小白自学]Spring(一) 项目:Spring-how2j-1 AOP重点

 

1.SpingIOC/DI

对Category的name属性注入了"category 1"字符串

2.Sping注入对象

对Product对象,注入一个Category对象

1.Product类包含Category

2.更改全局配置

3.编写测试类

3.Spring 注解方式 IOC/DI

使用注解的方式完成注入对象中的效果

1.在实体类那里@Component("") 声明这个类是bean

因为配置里没有初始化属性,所以在实体类声明属性的时候顺便初始化

2.全局配置

3.测试类

 

4.Spring AOP:(Aspect Oriented Program)面向切面(周边+核心功能)编程

AOP 即 Aspect Oriented Program 面向切面编程 
首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。 
所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务 
所谓的周边功能,比如性能统计,日志,事务管理等等 

周边功能在Spring的面向切面编程AOP思想里,即被定义为切面 

在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发 
然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP

 

 

1.新建一个业务类(也就是核心功能)

package com.service;

/**
 * 业务类,定义了一个doSomeService()方法的内容
 * @author Administrator
 *
 */
public class ProductService {
		public void doSomeService(){
			System.out.println("doSomeService方法");
		}
}

2.新建一个切面(本次例子是日志切面)

package com.aspect;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 日志切面LoggerAspect
 * 功能:在调用核心功能之前和之后分别打印日志
 * @author Administrator
 *
 */
public class LoggerAspect {
	public Object log(ProceedingJoinPoint joinPoint) throws Throwable{
		System.out.println("开始log:"+joinPoint.getSignature().getName());
		//proceed()启动目标方法,执行核心功能
		Object object = joinPoint.proceed();
		System.out.println("结束log:"+joinPoint.getSignature().getName());
		return object;
		
	}
}

3.修改全局配置(重点)

<?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:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context     
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<context:component-scan base-package="com.pojo" />

	<!-- <context:annotation-config/> 通过关键字c即可获取Category对象,该对象获取的时候,即被注入了字符串"category 
		1“到name属性中 -->
	<bean name="c" class="com.pojo.Category">
		<property name="name" value="这是c的name属性category 1" />
	</bean>

	<bean name="p" class="com.pojo.Product">
		<property name="name" value="这是p的name属性的product1" />
		<!--使用ref来注入另一个对象 -->
		<property name="category" ref="c" />
	</bean>

	<!--声明业务对象 -->
	<bean name="s" class="com.service.ProductService"></bean>

	<!--声明日志切面 -->
	<bean id="loggerAspect" class="com.aspect.LoggerAspect" />
	
	<!-- 通过aop:config把业务对象与辅助功能编织在一起 -->
	<aop:config>
		
		
		<!-- 切入点,切入service ,切入点的id叫loggerCutpoint,用来标记切入点.
		expression:满足expression里的方法后,就会进行切面操作
		execution(* com.service.ProductService.*(..)):返回包名以xx开头的类的任意方法		
		第一个*表示返回任意类型
		com.service.ProductService:表示包名以com.service.ProductService开头的任意方法
		第二个*表示任意方法
		(..)表示方法的参数是任意类型和任意数量
		-->
		<!--简单说就是,只要com.service这个包中的ProductService类的任意一个函数被调用,
		不管你的返回值是什么,都会触发开关,我就会去执行切面,也就是辅助功能  -->
		<aop:pointcut id="loggerCutpoint"
			expression="execution(* com.service.ProductService.*(..)) " />
		
		
		
		<!--下面是切面,日志就是一个切面(辅助功能),切面也可以说就是一个方法而已
		切入点可以理解为一个开光,触发了这个开关,就会执行这个切面
		id表示切面的名字
		ref:切面这个方法所在的类
		method:方法的名字
		pointcut-ref="loggerCutpoint" :把这个切面与上面的切点关联起来
		一个切点是可以关联多个切面的,一个切面只能关联一个方法
		  -->
		<aop:aspect id="logAspect" ref="loggerAspect">
			<!-- aop:around为在调用方法前,调用后执行 -->
			<aop:around pointcut-ref="loggerCutpoint" method="log" />
		</aop:aspect>
		
		
		<!-- 总结:配置一个切入点,然后再配置一个切面,然后把面放进去,
		相当于找到跳远的起点后,起点就是切入点,后面跳多少就是切面 -->
	</aop:config>


</beans>

 

4.测试类

 

 

5.运行结果

 

 

AOP的相关知识:

1.注解配置

在xml加入下面内容

添加如下3行
 
<context:component-scan base-package="com.how2java.aspect"/>
<context:component-scan base-package="com.how2java.service"/>
扫描包com.how2java.aspect和com.how2java.service,定位业务类和切面类

<aop:aspectj-autoproxy/>  
找到被注解了的切面类,进行切面配置

 

网站的功能分为核心功能和辅助功能,辅助功能叫做切面

 

AOP的过程分为两步:1,在业务类中插入切入点,2,将切入点和切面类关联起来

 

业务类就是核心类,就是网站的主要功能,切面就是辅助功能,日志,统计之类的

通过配置,可以实现,在某个方法调用的时候,触发别的方法执行,就好像在监视目标方法,你被执行,就触发我执行。

AOP术语

1,通知:

通知定义了切面要完成的工作内容和何时完成工作,就是什么时候去做辅助功能,功能具体是什么代码

五种类型

  1. Before——在方法调用之前调用通知

  2. After——在方法完成之后调用通知,无论方法执行成功与否

  3. After-returning——在方法执行成功之后调用通知

  4. After-throwing——在方法抛出异常后进行通知

  5. Around——通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为

 前四个好理解的,最后一个

around 表示切面在被监视的函数运行前后都会执行,

下面是切面要执行的函数 log,log函数有一个形参 joinPoint 这个可以理解为断点,中间一句代表的就是被监视的程序运行,在被监视的程序运行时,可以替换他的形参,这个是 around 厉害的地方,如果被监视的程序,运行的时候输入的是一个haha字符串作为实参,但是经过log方法之后,这个参数就被替换为abc了

public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("我在被监视程序之前。。。");
        Object object = joinPoint.proceed(new Object[]{"abc"});
        System.out.println("我在被监视程序之后。。。" );
        return object;
    }

 

 

2,连接点:

在执行正常的功能时,能够插入切面的点。可以作为切入点的点。备选点。

连接点可以是调用方法时、抛出异常时、甚至修改字段时,在这些点,就可以去执行切面。

 

3,切面: 

定义:切面是通知和切点的集合,通知和切点共同定义了切面的全部功能——它是什么,在何时何处完成其功能。

声明切面:

在Spring中,切面就是一个包含通知和切点的对象,是一个Bean,Bean的字段和方法就是该切面的状态和行为,还要通过配置,来指定切入点和通知实现

在xml中,切面使用<aop:aspect>标签指定,ref属性用来引用切面支持Bean。这个bean里面就是用来执行要做的辅助功能的。

 

 

4,切点:

定义:如果通知定义了“什么”和“何时”。那么切点就定义了“何处”。切点会匹配通知所要织入的一个或者多个连接点。通常使用明确的类或者方法来指定这些切点。

作用:定义通知被应用的位置(在哪些连接点)

切入点的声明:

切入点在Spring也是一个Bean。

切点的声明有三种定义方式:

1)在<aop:config>标签下使用<aop:pointcut>声明一个切入点Bean,该切入点可以被多个切面使用,对于需要共享使用的切入点最好使用该方式,该切入点使用id属性指定Bean名字,在通知定义时使用pointcut-ref属性通过该id引用切入点,expression属性指定切入点表达式

<aop:config>  
   <aop:pointcut id="pointcut" expression="execution(* cn.javass..*.*(..))"/>  
   <aop:aspect ref="aspectSupportBean">  
      <aop:before pointcut-ref="pointcut" method="before"/>  
   </aop:aspect>  
</aop:config>  

2)在<aop:aspect>标签下使用<aop:pointcut>声明一个切入点Bean,该切入点可以被多个切面使用,但一般该切入点只被该切面使用,当然也可以被其他切面使用,但最好不要那样使用,该切入点使用id属性指定Bean名字,在通知定义时使用pointcut-ref属性通过该id引用切入点,expression属性指定切入点表达式:

<aop:config>  
 <aop:aspect ref="aspectSupportBean">  
    <aop:pointcut id=" pointcut" expression="execution(* cn.javass..*.*(..))"/>  
    <aop:before pointcut-ref="pointcut" method="before"/>  
 </aop:aspect>  
</aop:config>  

3)匿名切入点Bean可以在声明通知时通过pointcut属性指定切入点表达式,该切入点是匿名切入点,只被该通知使用:

<aop:config>  
 <aop:aspect ref="aspectSupportBean">  
     <aop:after pointcut="execution(* cn.javass..*.*(..))" method="afterFinallyAdvice"/>  
 </aop:aspect>  
</aop:config>  

 

5,引入 

引入允许我们向现有的类中添加方法或属性

 

 

 

 

6,织入: 

织入是将切面应用到目标对象来创建的代理对象过程。

 

 

 

切面在指定的连接点被织入到目标对象中,在目标对象的生命周期中有多个点可以织入

 

 

  1. 编译期——切面在目标类编译时期被织入,这种方式需要特殊编译器。AspectJ的织入编译器就是以这种方式织入切面。
  2. 类加载期——切面在类加载到
  3. JVM ,这种方式需要特殊的类加载器,他可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5 的 LTW 就支持这种织入方式
  4. 运行期——切面在应用运行期间的某个时刻被织入。一般情况下,在织入切面时候,AOP 容器会为目标对象动态的创建代理对象。Spring AOP 就是以这种方式织入切面。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值