Spring通知(入门及使用方法)

Spring通知类型(入门使用方法)

需要导入的jar包

在这里插入图片描述

一.前置通知
作用:在目标方法执行之前执行的通知

1.定义一个含有业务方法的类

public class UserDao {	
	public void addUser(String name){
		System.out.println("addUser,name:"+name);
	}

2.前置通知类实现接口MethodBeforeAdvice中的方法

public class Log implements MethodBeforeAdvice {
	Logger log=Logger.getLogger("test.Log");
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2)
			throws Throwable {	
		log.info(Level.INFO+",写日志");

	}

3.配置beans.xml文件

<bean id="userDao" class="test.UserDao"/>
	<bean id="log" class="test.Log"/>	
	<!--  配置代理对象bean -->	
	<bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="userDao"></property>
		<property name="interceptorNames">
			<list>
				<value>log</value>
			</list>
		</property>
	</bean>

4.编写测试类

public class Test {
	public static void main(String[] args) {
        //获取bean容器
		ApplicationContext act=new ClassPathXmlApplicationContext("beans.xml");
		//获取代理对象
		UserDao userDaoProxy=(UserDao) act.getBean("userDaoProxy");
		userDaoProxy.addUser("lisi");		
	}
}
二.后置通知
作用:在目标方法执行之后执行

1.定义一个接口

public interface UserDaoIfac {
	public void addUser(String name);
}

2.创建实现接口的类

public class UserDao implements UserDaoIfac{
	public void addUser(String name)
	{
		System.out.println("addUser,name:"+name);	
	}
}

3.创建后置通知类实现AfterReturningAdvice接口中的afterReturning方法(调用目标对象方法后拦截)

public class RecordInterceptor implements AfterReturningAdvice {
	@Override
	public void afterReturning(Object arg0, Method method, Object[] arg2,
			Object arg3) throws Throwable {		
		System.out.println("ip 地址于"+new Date()+"访问方法"+method.getName());

	}

4.配置beans.xml文件

<bean id="userDao" class="test.UserDao"/>
	<bean id="RecordInterceptor" class="test.RecordInterceptor"/>	
	<!--  配置代理对象bean -->	
	<bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="userDao"></property>
		<property name="interceptorNames">
		<property name="proxyInterfaces" value="test.UserDaoIfac">
			<list>
				<value>recordInterceptor</value>
			</list>
		</property>
	</bean>

5.编写测试类

public class Test {
	public static void main(String[] args) {
        //获取bean容器
		ApplicationContext act=new ClassPathXmlApplicationContext("beans.xml");
		//获取代理对象
		UserDao userDaoProxy=(UserDao) act.getBean("userDaoProxy");
		userDaoProxy.addUser("lisi");		
	}
}
三.环绕通知
作用:围绕着目标方法执行

1.定义一个接口

public interface UserDaoIfac {
	public String addUser(String name);
}

2.创建实现接口的类

public class UserDao implements UserDaoIfac{
	public String addUser(String name)
	{
		System.out.println("addUser,name:"+name);	
	}
    return name;
}

3.创建环绕通知类实现MethodInterceptor接口中的invoke方法(调用目标对象方法会被关在这个方法中)

public class MyFilter implements MethodInterceptor{
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {		
		System.out.println("进来了");		
		//调用目标对象方法
		String result=(String)invocation.proceed();		
		System.out.println("走了");		
		return result;
	}

}

4.配置beans.xml

<bean id="userDao" class="test.UserDao"/>
	<bean id="myFilter" class="test.MyFilter"></bean>
	
	<bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="interceptorNames">
			<list>
				<value>myFilter</value>
			</list>
		</property>
		<!--  如果面向接口编程,需要配置接口信息 -->
		<property name="proxyInterfaces" value="test.UserDaoIfac"></property>
		<property name="target" ref="userDao"></property>
	</bean>

5.编写测试类

public class Test {
	public static void main(String[] args) {
        //获取bean容器
		ApplicationContext act=new ClassPathXmlApplicationContext("beans.xml");
		//获取代理对象
		UserDao userDaoProxy=(UserDao) act.getBean("userDaoProxy");
		userDaoProxy.addUser("lisi");		
	}
}
四.异常通知
作用:在目标方法抛出异常之后

1.定义一个接口

public interface UserDaoIfac {
	public String addUser(String name);
}

2.创建实现接口的类

public class UserDao implements UserDaoIfac{
	public String addUser(String name)
	{
		System.out.println("addUser,name:"+name);	
        int i = 2/0;//异常语句
	}
    return name;
}

3.创建异常通知类实现ThrowsAdvice接口中的afterThrowing方法(调用目标对象方法抛异常时执行)

public class MyExceptionAdvice implements ThrowsAdvice {
	public void afterThrowing(Exception ex)
	{
		System.out.println("异常信息 :"+ex.getMessage());
	}
	
}

4.配置beans.xml

<bean id="userDao" class="test.UserDao"/>	
	<bean id="myExceptionAdvice" class="test.MyExceptionAdvice"></bean>	
	<bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="interceptorNames">
			<list>
				<value>myExceptionAdvice</value>
			</list>
		</property>
		<!--  如果面向接口编程,需要配置接口信息 -->
		<property name="proxyInterfaces" value="test.UserDaoIfac"></property>
		<property name="target" ref="userDao"></property>
	</bean>

5.编写测试类

public class Test {
	public static void main(String[] args) {
        //获取bean容器
		ApplicationContext act=new ClassPathXmlApplicationContext("beans.xml");
		//获取代理对象
		UserDao userDaoProxy=(UserDao) act.getBean("userDaoProxy");
		userDaoProxy.addUser("lisi");		
	}
}

缺点:如果要对多个类进行拓展,那么就要手动配置多个bean代理,工作量大且不好维护。

SpringAOP之xmlConfig高级实现

1.定义一个含有业务方法的类

public class UserDao {
	public void addUser(String name)
	{
		System.out.println("addUser,name:"+name);
	}
	public void deleteUser(String name)
	{
		System.out.println("deleteUser,name:"+name);
	}
}

2.定义功能拓展类

前置通知记录日志

public class Log  {
	Logger log=Logger.getLogger("test.Log");
	public void before(){	
		log.info(Level.INFO+",写日志");
	}

后置通知记录ip

public class IPRecord {
	public  void ipRecord()
	{
		System.out.println("ipRecord");
	}
}

3.配置beans.xml 配置文件中多了3个AOP的属性文件

xmlns:aop=“http://www.springframework.org/schema/aop”

http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd

<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
	<bean id="userDao" class="test.UserDao"/>
	<bean id="log" class="test.Log"/>
	<bean id="iPRecord" class="test.IPRecord"/>
	
	<!-- 使用aop配置语法,配置切面,切入点和目标对象之间的关联关系 -->
	<aop:config>
		<!-- 可以配置多个,比如拦截dao的逻辑   比如拦截service的逻辑  比如拦截controller的逻辑都可以配置在这里 -->
		<aop:aspect id="myaspect" ref="log">
			<aop:pointcut expression="execution(* test.UserDao.add*(..))" id="addMethod"/>
			<aop:before method="before" pointcut-ref="addMethod"/>
		</aop:aspect>
		<aop:aspect id="mydeleteAspect" ref="iPRecord">
			<aop:pointcut expression="execution(* test..*.delete*(..))" id="deleteMethod"/>
			<aop:after method="ipRecord" pointcut-ref="deleteMethod"/>
		</aop:aspect>
	</aop:config>

</beans>
execution(* test.UserDao.add*(…)) 解释

{

*:不管方法有没有返回值

add*:test.UserDao下的所有add方法

(…):不管方法需不需要参数

}执行

4.编写测试类

public static void main(String[] args) {	
		ApplicationContext act=new ClassPathXmlApplicationContext("beans.xml");	
		UserDao userDao=(UserDao) act.getBean("userDao");
		userDao.addUser("张三");
		userDao.deleteUser("lisi");
	}

5.测试结果

在这里插入图片描述

SpringAOP之annotcation高级实现

1.定义一个含有业务方法的类

public class UserDao {
	public void addUser(String name)
	{
		System.out.println("addUser,name:"+name);
	}
	public void deleteUser(String name)
	{
		System.out.println("deleteUser,name:"+name);
	}
}

2.配置beans.xml

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

	<bean id="userDao" class="test.UserDao"/>
	<bean id="log" class="test.Log"/>
	<bean id="iPRecord" class="test.IPRecord"/>
	
	<!-- 使用注解,配置则写在拦截器上面,xml文件中要开启注解支持 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

3.使用注解编写功能拓展类

@Aspect:使其成为切面类

@Pointcut:切入点

@Before:前置通知

@After:后置通知

@Aspect   
public class Log  {	
	Logger log=Logger.getLogger("test.Log");

	@Pointcut("execution(* test.UserDao.add*(..))")
	private void addMethod(){}
	
	//怎么配置切谁  pointcut 通过一个傀儡方法配置
	@Before(value="addMethod()")//前置通知
	public void abc(){
		
		log.info(Level.INFO+",写日志");

	}

}
@Aspect
public class IPRecord {
	Logger log=Logger.getLogger("test.IPRecord");
	
	@Pointcut("execution(* test.UserDao.delete*(..))")
	private void deleteMethod(){}
	@After(value="deleteMethod()")
	public  void ipRecord()
	{
		log.info(Level.INFO+",ip地址");
	}

}

4.测试

public static void main(String[] args) {
		ApplicationContext act=new ClassPathXmlApplicationContext("beans.xml");
		
		UserDao userDao=(UserDao) act.getBean("userDao");
		/**
		 * 终于可以直接调用目标对象然后发现功能被扩展了
		 */
		userDao.addUser("张三");
		userDao.deleteUser("lisi");
		
	}

5.执行结果
在这里插入图片描述

常用表达式tips:

第一种:表示在UserMangeImpl类下的所有方法,这种方式在之前的案例使用的。

@Pointcut("execution(* com.spring.two.UserMangeImpl.*(..))")

第二种:表示任意公共的方法,其他修饰符也同样的道理。

 @Pointcut("execution(public * *(..))")

第三种:任何一个以set开始的方法,不仅仅是set,save、update也都行。

 @Pointcut("execution(* set*(..))")

第四种:在指定包下的所有方法

@Pointcut("execution(* com.spring.*.*(..))")
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值