Spring 4.x (二)
1 静态代理
- PersonDAO.java
package com.xuweiwei.staticproxy;
public interface PersonDAO {
public void save();
}
- PersonDAOImpl.java
package com.xuweiwei.staticproxy;
public class PersonDAOImpl implements PersonDAO {
@Override
public void save() {
System.out.println("保存用户信息");
}
}
- Transaction.java
package com.xuweiwei.staticproxy;
//事务
public class Transaction {
public void beginTransaction(){
System.out.println("开启事务");
}
public void commit(){
System.out.println("提交");
}
}
- PersonDAOProxyImpl.java
package com.xuweiwei.staticproxy;
public class PersonDAOProxyImpl implements PersonDAO {
private PersonDAO personDAO;
private Transaction transaction;
public PersonDAOProxyImpl(PersonDAO personDAO,Transaction transaction){
this.personDAO = personDAO;
this.transaction = transaction;
}
@Override
public void save() {
this.transaction.beginTransaction();
this.personDAO.save();
this.transaction.commit();
}
}
- 测试
package com.xuweiwei.staticproxy;
import org.junit.Test;
public class TestStatic {
@Test
public void test(){
PersonDAO personDAO = new PersonDAOImpl();
Transaction transaction = new Transaction();
PersonDAOProxyImpl proxy = new PersonDAOProxyImpl(personDAO,transaction);
proxy.save();
}
}
- 缺点:
- ①有多少DAO,就需要写多少proxy。
- ②如果目标方法有方法的改动,proxy也需要做对应的缺点。
2 动态代理
2.1 JDK动态代理--基于接口的动态代理
- PersonDAO.java
package com.xuweiwei.dynamicproxy;
public interface PersonDAO {
public void save();
}
- PersonDAOImpl.java
package com.xuweiwei.dynamicproxy;
public class PersonDAOImpl implements PersonDAO {
@Override
public void save() {
System.out.println("保存用户信息");
}
}
- MyInterceptor.java
package com.xuweiwei.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInterceptor implements InvocationHandler {
private Object target ;
private Transaction transaction;
public MyInterceptor(Object target, Transaction transaction) {
this.target = target;
this.transaction = transaction;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.transaction.beginTransaction();
Object result = method.invoke(target,args);//调用目标类的目标方法
this.transaction.commit();
return result;
}
}
- Transaction.java
package com.xuweiwei.dynamicproxy;
//事务
public class Transaction {
public void beginTransaction(){
System.out.println("开启事务");
}
public void commit(){
System.out.println("提交");
}
}
- 测试
package com.xuweiwei.dynamicproxy;
import org.junit.Test;
import java.lang.reflect.Proxy;
public class TestDynamic {
@Test
public void test(){
PersonDAO personDAO = new PersonDAOImpl();
Transaction transaction = new Transaction();
PersonDAO proxy = (PersonDAO) Proxy.newProxyInstance(personDAO.getClass().getClassLoader(),personDAO.getClass().getInterfaces(),new MyInterceptor(personDAO,transaction));
proxy.save();
}
}
- 问:拦截器中的invoke方法是在什么时候被调用的?
- 答:在代理对象调用方法的时候,进入拦截器中的invoke()方法。
- 问:拦截器中的method参数是什么?在什么时候由实参传递给形参?
- 答:代理对象调用方法的名称是什么,method参数就是什么。代理对象调用方法的时候,进入拦截器中的invoke()方法的时候,传递参数。
- 问:生成的代理对象实现了接口,代理对象的方法体的内容是什么?
- 答:代理对象方法体的内容就是拦截器中invoke()方法体的内容。
- 可以在拦截器中对指定的方法进行判断
package com.xuweiwei.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInterceptor implements InvocationHandler {
private Object target ;
private Transaction transaction;
public MyInterceptor(Object target, Transaction transaction) {
this.target = target;
this.transaction = transaction;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
if(method.getName().equals("save") || method.getName().equals("update")){
this.transaction.beginTransaction();
result = method.invoke(target,args);//调用目标类的目标方法
this.transaction.commit();
}else{
result = method.invoke(target,args);//调用目标类的目标方法
}
return result;
}
}
- 优点:动态代理产生的对象,只需要一个拦截器就OK了。
- 缺点:
- 如果invoke方法中需要判断,将是一件非常复杂的事情。
- 程序员需要写拦截器,写拦截器中的方法,所以invoke方法还需要修改
2.2 CGLIB动态代理--基于类的动态代理
- PersonDAO.java
package com.xuweiwei.dynamicproxy;
public class PersonDAO {
public void save(){
System.out.println("保存用户信息");
}
}
- MyInterceptor.java
package com.xuweiwei.dynamicproxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MyInterceptor implements MethodInterceptor {
private Object target ;
private Transaction transaction;
public MyInterceptor(Object target, Transaction transaction) {
this.target = target;
this.transaction = transaction;
}
public Object createProxy(){
Enhancer enhancer = new Enhancer();
enhancer.setCallback(this);//this表示拦截器对象
enhancer.setSuperclass(target.getClass());//设置代理类的父类为目标类
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
this.transaction.beginTransaction();
Object result = method.invoke(this.target,args);
this.transaction.commit();
return result;
}
}
- Transaction.java
package com.xuweiwei.dynamicproxy;
//事务
public class Transaction {
public void beginTransaction(){
System.out.println("开启事务");
}
public void commit(){
System.out.println("提交");
}
}
- 测试
package com.xuweiwei.dynamicproxy;
import org.junit.Test;
public class TestDynamic {
@Test
public void test(){
PersonDAO target = new PersonDAO();
Transaction transaction = new Transaction();
MyInterceptor interceptor = new MyInterceptor(target,transaction);
PersonDAO proxy = (PersonDAO) interceptor.createProxy();
proxy.save();
}
}
3 AOP的术语
- 以2.1中的代码为例



- 织入:形成代理对象的方法的过程就是织入。
- 【注意】
- 通知就是切面中的方法
- 代理对象的方法就是通知+目标方法
- 连接点就是目标接口中的一个方法
- 拦截器中的invoke方法就是代理对象的方法=通知+目标方法
- 在现实的开发中,通知和目标方法完全是松耦合的
4 XML方式的AOP
- PersonDAO.java
package com.xuweiwei.aop;
public interface PersonDAO {
public void savePerson();
}
- PersonDAOImpl.java
package com.xuweiwei.aop;
public class PersonDAOImpl implements PersonDAO {
@Override
public void savePerson() {
System.out.println("保存用户信息");
}
}
- Transaction.java
package com.xuweiwei.aop;
public class Transaction {
public void beginTransaction(){
System.out.println("开启事务");
}
public void commit(){
System.out.println("提交");
}
}
- appliationContext.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: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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 目标类 -->
<bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
<!-- 切面 -->
<bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
<!--
配置AOP
-->
<aop:config>
<!--
配置切入点
-->
<aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
<!--
配置切面
-->
<aop:aspect ref="transaction">
<!--
前置通知
-->
<aop:before method="beginTransaction" pointcut-ref="pointcut"/>
<!--
最终通知
-->
<aop:after method="commit" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
- 测试
package com.xuweiwei.test;
import com.xuweiwei.aop.PersonDAO;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAOP {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonDAO personDAO = (PersonDAO) context.getBean("personDAO");
personDAO.savePerson();
}
}
5 通知
- 前置通知:在目标方法执行之前
/**
* 前置通知
* JoinPoint:连接点,客户端调用那个方法,这个方法就是连接点
*/
public void beginTransaction(JoinPoint joinPoint){
System.out.println("目标类"+joinPoint.getTarget().getClass());
System.out.println("目标方法"+joinPoint.getSignature().getName());
System.out.println("目标类"+joinPoint.getArgs().length);
System.out.println("开启事务");
}
<?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"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 目标类 -->
<bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
<!-- 切面 -->
<bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
<!--
配置AOP
-->
<aop:config>
<!--
配置切入点
-->
<aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
<!--
配置切面
-->
<aop:aspect ref="transaction">
<!--
前置通知
-->
<aop:before method="beginTransaction" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
- 后置通知,在目标方法执行之后(如果目标方法产生异常,后置通知不执行)
package com.xuweiwei.aop;
public interface PersonDAO {
public String savePerson();
}
package com.xuweiwei.aop;
public class PersonDAOImpl implements PersonDAO {
@Override
public String savePerson() {
System.out.println("保存用户信息");
return "aa";
}
}
package com.xuweiwei.aop;
import org.aspectj.lang.JoinPoint;
public class Transaction {
/**
* 后置通知
* @param joinPoint
* @param val
*/
public void commit(JoinPoint joinPoint,Object val){
System.out.println("目标方法的返回值:"+val);
System.out.println("提交");
}
}
<?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"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 目标类 -->
<bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
<!-- 切面 -->
<bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
<!--
配置AOP
-->
<aop:config>
<!--
配置切入点
-->
<aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
<!--
配置切面
-->
<aop:aspect ref="transaction">
<!--
后置通知
-->
<aop:after-returning method="commit" pointcut-ref="pointcut" returning="val"/>
</aop:aspect>
</aop:config>
</beans>
- 异常通知:当发生异常的时候,此通知执行
package com.xuweiwei.aop;
public interface PersonDAO {
public String savePerson();
}
package com.xuweiwei.aop;
public class PersonDAOImpl implements PersonDAO {
@Override
public String savePerson() {
System.out.println("保存用户信息");
int a = 1/0;
return "aa";
}
}
package com.xuweiwei.aop;
import org.aspectj.lang.JoinPoint;
public class Transaction {
public void throwingMethod(JoinPoint joinPoint,Throwable ex){
System.out.println("发生异常:"+ex.getMessage());
System.out.println("异常通知");
}
}
<?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"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 目标类 -->
<bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
<!-- 切面 -->
<bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
<!--
配置AOP
-->
<aop:config>
<!--
配置切入点
-->
<aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
<!--
配置切面
-->
<aop:aspect ref="transaction">
<!--
异常通知
-->
<aop:after-throwing method="throwingMethod" pointcut-ref="pointcut" throwing="ex"/>
</aop:aspect>
</aop:config>
</beans>
- 最终通知:不管目标方法发生什么,都要执行此通知
package com.xuweiwei.aop;
public class Transaction {
public void finallyMethod(){
System.out.println("最终通知");
}
}
<?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"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 目标类 -->
<bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
<!-- 切面 -->
<bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
<!--
配置AOP
-->
<aop:config>
<!--
配置切入点
-->
<aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
<!--
配置切面
-->
<aop:aspect ref="transaction">
<!--
最终通知
-->
<aop:after method="finallyMethod" pointcut-ref="pointcut" />
</aop:aspect>
</aop:config>
</beans>
- 环绕通知:在目标方法执行前后,此通知执行
package com.xuweiwei.aop;
import org.aspectj.lang.ProceedingJoinPoint;
public class Transaction {
public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知执行前");
joinPoint.proceed();
System.out.println("环绕通知执行后");
}
}
<?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"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 目标类 -->
<bean id="personDAO" class="com.xuweiwei.aop.PersonDAOImpl"></bean>
<!-- 切面 -->
<bean id="transaction" class="com.xuweiwei.aop.Transaction"/>
<!--
配置AOP
-->
<aop:config>
<!--
配置切入点
-->
<aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.aop.PersonDAOImpl.*(..))"/>
<!--
配置切面
-->
<aop:aspect ref="transaction">
<!--
环绕通知
-->
<aop:around method="aroundMethod" pointcut-ref="pointcut" />
</aop:aspect>
</aop:config>
</beans>
- 示例:一个切入点跟多个切面
package com.xuweiwei;
public interface PersonDao {
public void savePerson();
}
package com.xuweiwei;
/**
* 目标类
*/
public class PersonDaoImpl implements PersonDao {
@Override
public void savePerson() {
System.out.println("保存用户信息");
}
}
package com.xuweiwei;
/**
* 切面
*/
public class Logger {
/**
* 通知
*/
public void logging(){
System.out.println("打印日志");
}
}
package com.xuweiwei;
/**
* 切面
*/
public class Transaction {
/**
* 通知
*/
public void beginTransaction(){
System.out.println("开启事务");
}
/**
* 通知
*/
public void commit(){
System.out.println("提交事务");
}
}
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!--
目标类
-->
<bean id="personDao" class="com.xuweiwei.PersonDaoImpl"></bean>
<!--
切面
-->
<bean id="transaction" class="com.xuweiwei.Transaction"></bean>
<!--
切面
-->
<bean id="logger" class="com.xuweiwei.Logger"></bean>
<!-- -->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.PersonDaoImpl.*(..) )"/>
<aop:aspect ref="logger">
<aop:before method="logging" pointcut-ref="pointcut"/>
</aop:aspect>
<aop:aspect ref="transaction">
<aop:before method="beginTransaction" pointcut-ref="pointcut"/>
<aop:after method="commit" pointcut-ref="pointcut" />
</aop:aspect>
</aop:config>
</beans>
package com.xuweiwei;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
@org.junit.Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonDao personDao = (PersonDao) context.getBean("personDao");
personDao.savePerson();
}
}
6 xml方式的AOP的案例---使用Spring AOP进行异常处理(对所有的service进行异常处理)
- dao层
- PersonDAO.java
package com.xuweiwei.exception.dao;
public interface PersonDAO {
public void savePerson() throws Exception;
}
- PersonDAOImpl.java
package com.xuweiwei.exception.dao.impl;
import com.xuweiwei.exception.dao.PersonDAO;
public class PersonDAOImpl implements PersonDAO{
@Override
public void savePerson() throws Exception {
int a = 1/ 0;
}
}
- service层
- PersonService.java
package com.xuweiwei.exception.service;
public interface PersonService {
public void savePerson() throws Exception;
}
- PersonServiceImpl.java
package com.xuweiwei.exception.service.impl;
import com.xuweiwei.exception.dao.PersonDAO;
import com.xuweiwei.exception.service.PersonService;
public class PersonServiceImpl implements PersonService {
private PersonDAO personDAO;
public PersonDAO getPersonDAO() {
return personDAO;
}
public void setPersonDAO(PersonDAO personDAO) {
this.personDAO = personDAO;
}
@Override
public void savePerson() throws Exception {
personDAO.savePerson();
}
}
- action
- PersonAction.java
package com.xuweiwei.exception.action;
import com.xuweiwei.exception.service.PersonService;
public class PersonAction {
private PersonService personService;
public PersonService getPersonService() {
return personService;
}
public void setPersonService(PersonService personService) {
this.personService = personService;
}
public void savePerson(){
try {
this.personService.savePerson();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
- aspect(异常切面)
- ExceptionAspect.java
package com.xuweiwei.exception.aspect;
import org.aspectj.lang.JoinPoint;
import javax.servlet.http.HttpServletResponse;
//异常的切面
public class ExceptionAspect {
//处理异常的通知
public void hanleException(JoinPoint joinPoint, Throwable ex){
printLog(ex);
}
private void printLog(Throwable ex) {
}
}
- applicationContext.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: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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- dao -->
<bean id="personDAO" class="com.xuweiwei.exception.dao.impl.PersonDAOImpl"/>
<!-- service -->
<bean id="personService" class="com.xuweiwei.exception.service.impl.PersonServiceImpl">
<property name="personDAO" ref="personDAO"/>
</bean>
<bean id="personAction" class="com.xuweiwei.exception.action.PersonAction">
<property name="personService" ref="personService"/>
</bean>
<!-- 切面 -->
<bean id="aspect" class="com.xuweiwei.exception.aspect.ExceptionAspect"></bean>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.xuweiwei.exception.service.*.*(..))"/>
<aop:aspect ref="aspect">
<aop:after-throwing method="hanleException" throwing="ex" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
- 测试
package com.test;
import com.xuweiwei.exception.action.PersonAction;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestException {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonAction personAction = (PersonAction) context.getBean("personAction");
personAction.savePerson();
}
}
7 注解方式的AOP
- 步骤:
- ①在applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<context:component-scan base-package="com.xuweiwei"/>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
- ②在切面类中设置@Component和@Aspect,以及切入点,请看下面
package com.xuweiwei;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* 切面
*/
@Component
@Aspect //此注解表明这是一个切面
public class Transaction {
//设置切入点
@Pointcut("execution( * com.xuweiwei.PersonDaoImpl.*(..))")
private void pointcut(){}
/**
* 设置前置通知
*/
@Before("pointcut()")
public void beginTransaction(){
System.out.println("开启事务");
}
/**
* 设置最终通知
*/
@After("pointcut()")
public void commit(){
System.out.println("提交事务");
}
}
package com.xuweiwei;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* 切面
*/
@Component
@Aspect
public class Logger {
//设置切入点
@Pointcut("execution(* com.xuweiwei.PersonDaoImpl.*(..))")
private void pointcut(){}
/**
* 设置前置通知
*/
@After("pointcut()")
public void logging(){
System.out.println("打印日志");
}
}
- 目标类实现的接口和目标类
package com.xuweiwei;
public interface PersonDao {
public void savePerson();
}
package com.xuweiwei;
import org.springframework.stereotype.Component;
/**
* 目标类
*/
@Component("personDao")
public class PersonDaoImpl implements PersonDao {
@Override
public void savePerson() {
System.out.println("保存用户信息");
}
}
- 测试
package com.xuweiwei;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
@org.junit.Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonDao personDao = (PersonDao) context.getBean("personDao");
personDao.savePerson();
}
}
Spring 4.x (二)的更多相关文章
- spring boot / cloud (二) 规范响应格式以及统一异常处理
spring boot / cloud (二) 规范响应格式以及统一异常处理 前言 为什么规范响应格式? 我认为,采用预先约定好的数据格式,将返回数据(无论是正常的还是异常的)规范起来,有助于提高团队 ...
- Spring Data(二)查询
Spring Data(二)查询 接着上一篇,我们继续讲解Spring Data查询的策略. 查询的生成 查询的构建机制对于Spring Data的基础是非常有用的.构建的机制将截断前缀find-By ...
- spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求
spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求 有半年多没有更新了,按照常规剧本,应该会说项目很忙,工作很忙,没空更新,吧啦吧啦,相关的话吧, 但是细想想 ...
- Spring IOC(二)容器初始化
本系列目录: Spring IOC(一)概览 Spring IOC(二)容器初始化 Spring IOC(三)依赖注入 Spring IOC(四)总结 目录 一.ApplicationContext接 ...
- 深入理解Spring AOP之二代理对象生成
深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...
- spring AOP 之二:@AspectJ注解的3种配置
@AspectJ相关文章 <spring AOP 之二:@AspectJ注解的3种配置> <spring AOP 之三:使用@AspectJ定义切入点> <spring ...
- Spring Boot 2 (二):Spring Boot 2 动态 Banner
Spring Boot 2 (二):Spring Boot 2 动态 Banner Spring Boot 2.0 提供了很多新特性,其中就有一个小彩蛋:动态 Banner. 一.配置依赖 使用 Sp ...
- Spring Boot(十二):spring boot如何测试打包部署
Spring Boot(十二):spring boot如何测试打包部署 一.开发阶段 1,单元测试 在开发阶段的时候最重要的是单元测试了,springboot对单元测试的支持已经很完善了. (1)在p ...
- (转)Spring Cloud(二)
(二期)23.微服务框架spring cloud(二) [课程23]熔断器-Hystrix.xmind0.1MB [课程23]微服务...zuul.xmind0.2MB 熔断器-Hystrix 雪崩效 ...
- spring cloud: zuul(二): zuul的serviceId/service-id配置(微网关)
spring cloud: zuul(二): zuul的serviceId/service-id配置(微网关) zuul: routes: #路由配置表示 myroute1: #路由名一 path: ...
随机推荐
- 第一个程序python.py
print("hello word")print("hello hello")print("hello hello")print(" ...
- 为什么arguments是类数组对象
为什么JavaScript里函数的arguments只是array-like object? 只是标准这么规定的,还是有什么设计原因在里面?JavaScript的函数里面的arguments对象有 . ...
- asp.net core 配置
ASP.NET Core的配置系统已经和之前版本的ASP.NET有所不同了,之前是依赖于System.Configuration和XML配置文件web.config,现在支持各种格式的配置,比以前灵活 ...
- python子域名收集器
今天心血来潮做了一个子域名收集器.过程是蛋疼啊!这里先感谢一下qpython群的咸鱼大佬,在换页的时候出了点毛病,讲到后面我们就知道了. 思路: 代码开始: 我们要用到的模块是 Requests Bs ...
- JavaSE(一)之类与对象
终于到了要学习面向对象程序设计了,其中可能很多东西以前都知道怎么去用,但是却不知道怎么来的,或者怎么样写会出错,所以今天总结起来. 一.OOP概述 Java的编程语言是面向对象的,采用这种语言进行编程 ...
- zoj 3228:Searching the String
Description Little jay really hates to deal with string. But moondy likes it very much, and she's so ...
- [bzoj1969] [Ahoi2005]LANE 航线规划
tarjan.并查集.树状数组.树链剖分. 时间倒流,变删边为加边. 先求一波边双联通分量,缩点. 题目保证最后还是整张图联通的..所以就是一棵树. 现在的操作就是,将路径上的边权置0(加边时),查询 ...
- HDU6038-Function-数学+思维-2017多校Team01
学长讲座讲过的,代码也讲过了,然而,当时上课没来听,听代码的时候也一脸o((⊙﹏⊙))o 我的妈呀,语文不好是硬伤,看题意看了好久好久好久(死一死)... 数学+思维题,代码懂了,也能写出来,但是还是 ...
- c++(递归和堆栈)
看过我前面博客的朋友都清楚,函数调用主要依靠ebp和esp的堆栈互动来实现的.那么递归呢,最主要的特色就是函数自己调用自己.如果一个函数调用的是自己本身,那么这个函数就是递归函数. 我们可以看一下普通 ...
- 浅谈MySQL集群高可用架构
前言 高可用架构对于互联网服务基本是标配,无论是应用服务还是数据库服务都需要做到高可用.对于一个系统而言,可能包含很多模块,比如前端应用,缓存,数据库,搜索,消息队列等,每个模块都需要做到高可用,才能 ...