久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Spring面向切面

 藏經(jīng)閣_蒼穹 2016-03-17
1.AspectJ - AOP

面向切面編程是面向?qū)ο蟮囊粋€補充

在保存用戶前添加一個日志,再加上時刻的記錄,。 總之,,就是方法前后加一點業(yè)務(wù)邏輯

新建資源庫:
Preference>Java>BuildPath>UserLibraries,AddLibrary>UserLibrary

/Spring_AOP/src/yuki/spring/aop/imitate/UserService.java

package yuki.spring.aop.imitate;

public interface UserService {

    void save();
}

/Spring_AOP/src/yuki/spring/aop/imitate/UserServiceImpl.java

package yuki.spring.aop.imitate;

public class UserServiceImpl implements UserService{

    public void save(){
        System.out.println("user saved...");
    }
}

/Spring_AOP/src/yuki/spring/aop/imitate/Intercepter.java

package yuki.spring.aop.imitate;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public abstract class Intercepter implements InvocationHandler {

  private Object target;
  public void setTarget(Object target) {
    this.target = target;
  }
  
  protected abstract void beforeMethod();
  protected abstract void afterMethod();
  
  @Override
  public Object invoke(Object proxy, Method m, Object[] args)
      throws Throwable {
    beforeMethod();
    m.invoke(target, args);
    afterMethod();
    return null;
  }

}

/Spring_AOP/src/yuki/spring/aop/imitate/LogIntercepter.java

package yuki.spring.aop.imitate;

public class LogIntercepter extends Intercepter {

  @Override
  public void beforeMethod() {
    System.out.println("log start...");
  }

  @Override
  protected void afterMethod() {
    System.out.println("log end...");
  }

}

/Spring_AOP/src/yuki/spring/aop/imitate/TimeIntercepter.java

package yuki.spring.aop.imitate;

public class TimeIntercepter extends Intercepter {

  @Override
  protected void beforeMethod() {
    System.out.println("start:" + System.currentTimeMillis());
  }

  @Override
  protected void afterMethod() {
    System.out.println("end:" + System.currentTimeMillis());
  }

}

/Spring_AOP/src/yuki/spring/aop/imitate/ProxyTest.java

package yuki.spring.aop.imitate;

import java.lang.reflect.Proxy;

public class ProxyTest {

  public static void main(String[] args) {
    UserService service = new UserServiceImpl();
    
    Intercepter[] intercepters = {new LogIntercepter(), new TimeIntercepter()};
    for(Intercepter intercepter : intercepters){
      intercepter.setTarget(service);
      service = (UserService) Proxy.newProxyInstance(
          service.getClass().getClassLoader(), 
          service.getClass().getInterfaces(), intercepter);
    }
    
    service.save();
    
  }

}

上面的程序中,,兩個類繼承了實現(xiàn)InvocationHandler接口的抽象類,,

也可以說是間接地實現(xiàn)了InvocationHandler接口;

聲明為UserService接口類型的service,,

在循環(huán)中每一次接收Proxy.newProxyInstance方法的計算結(jié)果后就會改變它指向的對象。

運行結(jié)果如下:

start:1409496143248
log start...
user saved...
log end...
end:1409496143250

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

注解的方式實現(xiàn)AOP使用的是aspectj,,

aspectj是專門用來產(chǎn)生動態(tài)代理的一個框架

可以使用aspectj注解的方式實現(xiàn)spring的AOP,,

把這個邏輯織入到原來的邏輯里面去

引入jar:aspectjrt.jar、aspectj-weaver.jar:http://www./Code/Jar/a/aspectj.htm

在類上添加注解 @Aspect和 @Component,在方法上添加注解 @Before

切入點語法 @Before("execution(public void yuki.spring.aop.annotation"

+ ".UserServiceImpl.save(yuki.spring.aop.annotation.User))")

引入jar:aopalliance-.jar:

http://www./Code/Jar/a/Downloadaopalliancejar.htm

@Component要加在對應(yīng)的實現(xiàn)類上,,因為getBean后要獲取這個對象

/Spring_AOP/src/yuki/spring/aop/annotation/User.java

package yuki.spring.aop.annotation;

public class User {

}

/Spring_AOP/src/yuki/spring/aop/annotation/UserService.java

package yuki.spring.aop.annotation;

public interface UserService {

    void save(User user);
}

/Spring_AOP/src/yuki/spring/aop/annotation/UserServiceImpl.java

package yuki.spring.aop.annotation;

import org.springframework.stereotype.Component;

@Component("userService")
public class UserServiceImpl implements UserService{

    public void save(User user){
        System.out.println("user saved...");
    }
}

/Spring_AOP/src/annotation.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www./schema/aop"
    xmlns:context="http://www./schema/context" 
    xmlns="http://www./schema/beans"
    xmlns:xsi="http://www./2001/XMLSchema-instance"
    xsi:schemaLocation="http://www./schema/beans 
      http://www./schema/beans/spring-beans-4.0.xsd 
      http://www./schema/aop 
      http://www./schema/aop/spring-aop-4.0.xsd 
      http://www./schema/context 
      http://www./schema/context/spring-context-4.0.xsd ">
    
    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="yuki.spring.aop.annotation"></context:component-scan>
    
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
</beans>

/Spring_AOP/src/yuki/spring/aop/annotation/LogIntercepter.java

package yuki.spring.aop.annotation;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogIntercepter {

    @Before("execution(public void yuki.spring.aop.annotation"
            + ".UserServiceImpl.save(yuki.spring.aop.annotation.User))")
    public void beforeMethod() {
        System.out.println("method start...");
    }

}

/Spring_AOP/src/yuki/spring/aop/annotation/TimeIntercepter.java

package yuki.spring.aop.annotation;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TimeIntercepter {

  @Before("execution("
      + "public * yuki.spring.aop.annotation..*.*(..)"
      + ")")
  public void beforeMethod() {
    System.out.println("before:" + System.currentTimeMillis());
  }

  @AfterReturning("execution( public * yuki.spring.aop.annotation..*.*(..) )")
  public void afterReturningMethod() {
    System.out.println("afterReturning:" + System.currentTimeMillis());
  }
}

/Spring_AOP/src/yuki/spring/aop/annotation/PointcutIntercepter.java

package yuki.spring.aop.annotation;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class PointcutIntercepter {

  @Pointcut("execution( public * yuki.spring.aop.annotation..*.*(..) )")
  public void myMethod() {}
  
  @Before("myMethod()")
  public void beforeMethod() {
    System.out.println("PointcutIntercepter::before");
  }

  @AfterReturning("myMethod()")
  public void afterReturningMethod() {
    System.out.println("PointcutIntercepter::afterReturning");
  }
}

/Spring_AOP/src/yuki/spring/aop/annotation/UserServiceTest.java

package yuki.spring.aop.annotation;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

  @Test
  public void testSave() {
    
    @SuppressWarnings("resource")
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("annotation.xml");
    UserService service = (UserService) context.getBean("userService");
    service.save(new User());
    context.destroy();
  }

}

運行結(jié)果如下:

八月 31, 2014 10:59:10 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1637f22: startup date [Sun Aug 31 22:59:10 CST 2014]; root of context hierarchy
八月 31, 2014 10:59:10 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [annotation.xml]
method start...
PointcutIntercepter::before
before:1409497152268
user saved...
afterReturning:1409497152268
PointcutIntercepter::afterReturning
八月 31, 2014 10:59:12 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1637f22: startup date [Sun Aug 31 22:59:10 CST 2014]; root of context hierarchy

術(shù)語解釋:

JoinPoint:連接點,、切入點,在哪里把邏輯加進區(qū)

PointCut:JoinPoint的集合,,可以一次性定義好多切入點

Aspect:切面,,切面類加進去的邏輯可以認為是一個切面

Advice:在這個點上建議怎么辦,比如 @Before

Target:被織入邏輯的被代理對象

Weave:織入

2.切面和通知

切入點:

// the execution of any public method:

execution(public * *(..))

// the execution of any method with a name beginning with "set":

execution(* set*(..))

// the execution of any method defined by the AccountService interface:

execution(* com.xyz.service.AccountService.*(..))

// the execution of any method defined in the service package:

execution(* com.xyz.service..(..))

// the execution of any method defined in the service package or a sub-package:

execution(* com.xyz.service..*.*(..))

spring也定義了自己的織入點語法,,但是我們只要用AspectJ的語法就可以了

通知:

Before,、AfterReturn、AfterThrowing,、After(意思是finally)

Around:在ProceedingJoinPoint.proceed()前后加邏輯

如果織入點表達式相同,,可以定義Pointcut

定義方法名接收織入點表達式的值,使用時 @AfterReturning("pointcut()")

/Spring_AOP/src/yuki/spring/aop/pointcut/User.java

package yuki.spring.aop.pointcut;

public class User {

}

/Spring_AOP/src/yuki/spring/aop/pointcut/UserService.java

package yuki.spring.aop.pointcut;

public interface UserService {

    void save(User user);
}

/Spring_AOP/src/yuki/spring/aop/pointcut/UserServiceImpl.java

package yuki.spring.aop.pointcut;

import org.springframework.stereotype.Component;

@Component("userService")
public class UserServiceImpl implements UserService{

    public void save(User user){
        System.out.println("user saved...");
        //throw new RuntimeException("exception...");
    }
}

/Spring_AOP/src/yuki/spring/aop/pointcut/TransactionAspect.java

package yuki.spring.aop.pointcut;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TransactionAspect {

  @Pointcut("execution( public * yuki.spring.aop.pointcut..*.*(..) )")
  public void pointcut(){}
  
  @Before("pointcut()")
  public void before(){
    System.out.println("before");
  }
  @AfterReturning("pointcut()")
  public void afterReturning(){
    System.out.println("afterReturning");
  }
  @AfterThrowing("pointcut()")
  public void afterThrowing(){
    System.out.println("afterThrowing");
  }
  
  @Around("pointcut()")
  public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
    System.out.println("method around start...");
    pjp.proceed();
    System.out.println("method around end...");
  }
  
}

/Spring_AOP/src/pointcut.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www./schema/aop"
    xmlns:context="http://www./schema/context" 
    xmlns="http://www./schema/beans"
    xmlns:xsi="http://www./2001/XMLSchema-instance"
    xsi:schemaLocation="http://www./schema/beans 
      http://www./schema/beans/spring-beans-4.0.xsd 
      http://www./schema/aop 
      http://www./schema/aop/spring-aop-4.0.xsd 
      http://www./schema/context 
      http://www./schema/context/spring-context-4.0.xsd ">
    
    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="yuki.spring.aop.pointcut"></context:component-scan>
    
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
</beans>

/Spring_AOP/src/yuki/spring/aop/pointcut/UserServiceTest.java

package yuki.spring.aop.pointcut;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

  @Test
  public void testSave() {
    
    @SuppressWarnings("resource")
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("pointcut.xml");
    UserService service = (UserService) context.getBean("userService");
    service.save(new User());
    context.destroy();
  }

}

運行結(jié)果如下:

八月 31, 2014 11:09:22 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1637f22: startup date [Sun Aug 31 23:09:22 CST 2014]; root of context hierarchy
八月 31, 2014 11:09:22 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [pointcut.xml]
method around start...
before
user saved...
method around end...
afterReturning
八月 31, 2014 11:09:24 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1637f22: startup date [Sun Aug 31 23:09:22 CST 2014]; root of context hierarchy

可以實現(xiàn)聲明式的異常管理,,

struts2已經(jīng)實現(xiàn)了聲明式的異常管理,,

這里略過通知執(zhí)行的先后順序

3.cglib

如果被代理的類實現(xiàn)了接口, 

就會使用JDK自帶的Proxy和InvocationHandler來實現(xiàn)代理

當被代理的類沒有實現(xiàn)接口,, 

它會用cglib直接操作二進制碼的形式來產(chǎn)生代理的代碼

引入jar:cglib-2.2.jar:http://www./Code/Jar/c/Downloadcglib22jar.htm

/Spring_AOP/src/yuki/spring/aop/cglib/UserService.java

package yuki.spring.aop.cglib;

import org.springframework.stereotype.Component;

@Component
public class UserService {

    public void save(){
        System.out.println("user saved...");
    }
}

/Spring_AOP/src/yuki/spring/aop/cglib/CglibAspect.java

package yuki.spring.aop.cglib;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class CglibAspect {

  @Pointcut("execution( public * yuki.spring.aop.cglib..*.*(..) )")
  public void pointcut(){}
  
  @Around("pointcut()")
  public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
    System.out.println("method around start...");
    pjp.proceed();
    System.out.println("method around end...");
  }
  
}

/Spring_AOP/src/cglib.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www./schema/aop"
    xmlns:context="http://www./schema/context" 
    xmlns="http://www./schema/beans"
    xmlns:xsi="http://www./2001/XMLSchema-instance"
    xsi:schemaLocation="http://www./schema/beans 
      http://www./schema/beans/spring-beans-4.0.xsd 
      http://www./schema/aop 
      http://www./schema/aop/spring-aop-4.0.xsd 
      http://www./schema/context 
      http://www./schema/context/spring-context-4.0.xsd ">
    
    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="yuki.spring.aop.cglib"></context:component-scan>
    
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
</beans>

/Spring_AOP/src/yuki/spring/aop/cglib/UserServiceTest.java

package yuki.spring.aop.cglib;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

  @Test
  public void testSave() {
    
    @SuppressWarnings("resource")
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("cglib.xml");
    UserService service = (UserService) context.getBean("userService");
    System.out.println(service.getClass());
    service.save();
    context.destroy();
  }

}

運行結(jié)果如下:

八月 31, 2014 11:14:17 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1637f22: startup date [Sun Aug 31 23:14:17 CST 2014]; root of context hierarchy
八月 31, 2014 11:14:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [cglib.xml]
class yuki.spring.aop.cglib.UserService$$EnhancerBySpringCGLIB$$b8ea6837
method around start...
user saved...
method around end...
八月 31, 2014 11:14:19 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1637f22: startup date [Sun Aug 31 23:14:17 CST 2014]; root of context hierarchy

4.xml:AOP

pointcut可以聲明在aspect的里面或外面

eclipse:從源碼視圖切換到設(shè)計視圖

在執(zhí)行UserService.save()時,,發(fā)現(xiàn)符合配置的切入點表達式

對應(yīng)的是LogAspect.before(),于是先執(zhí)行before,,然后save()

可以直接指定pointcut,,也可以在外部指定然后再引用它

如果使用第三方類的切面類邏輯,那么就必須要使用xml配置的方式

/Spring_AOP/src/yuki/spring/aop/xml/UserService.java

package yuki.spring.aop.xml;

import org.springframework.stereotype.Component;

@Component("userService")
public class UserService {

    public void save(){
        System.out.println("user saved...");
    }
}

/Spring_AOP/src/yuki/spring/aop/xml/LogAspect.java

package yuki.spring.aop.xml;

public class LogAspect {

    public void before() {
        System.out.println("method start...");
    }

}

/Spring_AOP/src/xml.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www./schema/aop"
    xmlns:context="http://www./schema/context" 
    xmlns="http://www./schema/beans"
    xmlns:xsi="http://www./2001/XMLSchema-instance"
    xsi:schemaLocation="http://www./schema/beans 
      http://www./schema/beans/spring-beans-4.0.xsd 
      http://www./schema/aop 
      http://www./schema/aop/spring-aop-4.0.xsd 
      http://www./schema/context 
      http://www./schema/context/spring-context-4.0.xsd ">
    
    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="yuki.spring.aop.xml"></context:component-scan>
    
    <bean id="logAspect" class="yuki.spring.aop.xml.LogAspect"></bean>
    <!-- 
    <aop:config>
        <aop:pointcut id="servicePointcut"
                expression="execution( public * yuki.spring.aop.xml..*.*(..) )" />
        <aop:aspect id="logAspect" ref="logAspect">
            <aop:before method="before" pointcut-ref="servicePointcut"/>
        </aop:aspect>
    </aop:config>
     -->

    <aop:config>
        <aop:aspect id="logAspect" ref="logAspect">
            <aop:before method="before" 
  pointcut="execution( public * yuki.spring.aop.xml..*.*(..) )"/>
        </aop:aspect>
    </aop:config>

</beans>

/Spring_AOP/src/yuki/spring/aop/xml/UserServiceTest.java

package yuki.spring.aop.xml;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

  @Test
  public void testSave() {
    
    @SuppressWarnings("resource")
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("xml.xml");
    UserService service = (UserService) context.getBean("userService");
    service.save();
    context.destroy();
  }

}

運行結(jié)果如下:

八月 31, 2014 11:19:01 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1637f22: startup date [Sun Aug 31 23:19:01 CST 2014]; root of context hierarchy
八月 31, 2014 11:19:01 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [xml.xml]
method start...
user saved...
八月 31, 2014 11:19:02 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1637f22: startup date [Sun Aug 31 23:19:01 CST 2014]; root of context hierarchy

5.tomcat debug的熱部署

在tomcat的jdk虛擬機參數(shù)中添加

-Dcom.sun.management.jmxremote=true

如果修改配置文件,,使用了自定義標簽的jsp頁面,,修改了注解,等等情況:還是要重啟服務(wù)器的

在方法內(nèi)部修改代碼,,不用重啟服務(wù)器,,這已經(jīng)是很大的便捷了,

有興趣的小伙伴們?nèi)パ芯抗δ芨鼜姶蟮臒岵渴鸢?。,。?!?/span>

目錄結(jié)構(gòu):

本文參考了[尚學堂馬士兵_Spring_AOP]的公開課程

更多好文請關(guān)注:http://www.cnblogs.com/kodoyang/

>*_*<

kongdongyang

2014/8/31

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多