Existem cinco reforço da mola: BeforeAdvide (pré-reforço), AfterAdvice (reforço traseiro), ThrowsAdvice (aumento anormal), RoundAdvice (reforço envolvente), IntroductionAdvice (reforço incorporados)
RoundAdvice (Enhanced Surround): é BeforeAdvide (pré-realce), uma combinação AfterAdvice (post-boost) é chamado usando o reforço surround.
As quatro primeiras melhorias são relativamente simples, temos de introduzir o conceito e princípio IntroductionAdvice (introduzido avançado) de.
Introduzindo o conceito de avançado (Introdução Advice) para: uma classe Java não implementa a interface A, sem modificar classe Java, que tem uma função de interface A.
1.Cglib conseguir a introdução de reforçada
Lembre-se, meu propósito não é dizer-lhe como usar aprimoramentos introduzidos na Primavera (Este não é o meu estilo), mas sim para explorar a introdução de recursos avançados para alcançar o princípio subjacente.
public interface IHello {
public void sayHello();
}
A descrição acima é uma função de interface, é a necessidade de reforçar as classes CeremonyService, sem alterar classe CeremonyService, tem a função de interface IHello.
public class CeremenyService {
public void sayBye() {
System.out.println("Say bye from Ceremeny.");
}
}
Para ter esta aparência:
CeremenyService cs;
IHello ih = (IHello) cs;
ih.sayHello();
Ou seja, CeremenyService realmente se transformou em tipo IHello.
Nós escrevemos um importante interceptores para implementar este recurso.
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import x.y.IHello;
public class IntroInterceptor implements MethodInterceptor, IHello {
// 实现了IHello增强接口的对象
private Object delegate;
public IntroInterceptor() {
this.delegate = this;
}
public IntroInterceptor(Object delegate) {
this.delegate = delegate;
}
@Override
public void sayHello() {
System.out.println("Say hello from delegate.");
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Class<?> clz = method.getDeclaringClass();
if (clz.isAssignableFrom(IHello.class)) {
// 如果实现了IHello增强接口,则调用实现类delegate的方法
return method.invoke(delegate, args);
}
return methodProxy.invokeSuper(obj, args);
}
}
Vamos escrever uma classe de teste.
public static void main(String[] args) {
Enhancer en = new Enhancer();
en.setSuperclass(CeremenyService.class);
en.setInterfaces(new Class[] { IHello.class });
en.setCallback(new IntroInterceptor());
CeremenyService cs = (CeremenyService) en.create();
cs.sayBye();
IHello ih = (IHello) cs;
ih.sayHello();
}
en.setInterfaces (nova classe [] {IHello.class}); importantes, representa cglib gerado classe de proxy, definir a interface para ser conseguida.
Assim gerado Classe classe de proxy, como:public class CeremenyService$$EnhancerByCGLIB$$86859be5 extends CeremenyService implements IHello
saída:
Say bye from Ceremeny.
Say hello from delegate.
Esta é a base da famosa introdução de (Advice Introdução) princípio implementação reforçada.
2. framework Spring interpretação código introduzido fonte melhorada
arquivo de configuração XML do Spring.
<bean id="ceremonyService" class="x.y.service.CeremonyService" />
<bean id="ceremonyIntroAdvice" class="x.y.advice.CeremonyIntroAdvice" />
<bean id="ceremonyProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces" value="x.y.IHello"/> <!-- 需要动态实现的接口 -->
<property name="target" ref="ceremonyService"/> <!-- 目标类 -->
<property name="interceptorNames" value="ceremonyIntroAdvice"/> <!-- 引入增强 -->
<property name="proxyTargetClass" value="true"/> <!-- 代理目标类(默认为 false,代理接口) -->
</bean>
Precisamos de um interceptor personalizado.
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
import x.y.IHello;
@SuppressWarnings("serial")
public class CeremonyIntroAdvice extends DelegatingIntroductionInterceptor implements IHello {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
return super.invoke(mi);
}
@Override
public void sayHello() {
System.out.println("Say hello.");
}
}
Na Primavera, a introdução de melhorias para conseguir, precisa herdar de DelegatingIntroductionInterceptor.
Veja DelegatingIntroductionInterceptor invocar o método seguinte classe () da fonte.
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 检测是否是引入增强
if (isMethodOnIntroducedInterface(mi)) {
// 执行实现了引入增强接口的delegate对象的增强方法
Object retVal = AopUtils.invokeJoinpointUsingReflection(this.delegate, mi.getMethod(), mi.getArguments());
// Massage return value if possible: if the delegate returned itself,
// we really want to return the proxy.
if (retVal == this.delegate && mi instanceof ProxyMethodInvocation) {
Object proxy = ((ProxyMethodInvocation) mi).getProxy();
if (mi.getMethod().getReturnType().isInstance(proxy)) {
retVal = proxy;
}
}
return retVal;
}
return doProceed(mi);
}
método interno AopUtils.invokeJoinpointUsingReflection (), na verdade, reflete chamada de método.
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
Finalmente, escrever um método de teste para teste.
public static void main(String[] args) {
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(
"D:/workspace/Spring4.2.5/bin/applicationContext.xml");
CeremonyService service = context.getBean("ceremonyProxy", CeremonyService.class);
service.sayBye();
IHello hello = (IHello) service;
hello.sayHello();
context.close();
}
saída:
Say bye.
Say hello.
resumo
Alta qualidade shangyepingtai.xin programação de vídeo
O artigo descreve como usar mais, mas menos descreve o princípio do artigo, eu prefiro a introduzir o princípio do artigo. Espero que este post útil.