点击阅读原文进入 另为了挣到10000块,他在VSRC投了一篇稿!
关于代理
代理即proxy,应用开发中经常使用proxy层去代理处理请求,即让别人代替你去处理。
上面一个demo,一个接口和实现类。如果想在println方法前面和后面分别需要处理一些逻辑,要怎么做呢?把这些逻辑写死在say方法里面吗?菜鸟才会这么干!
代理模式就派上用场了。写一个GreetingProxy类,让他去调用GreetingImpl的sayHello方法,在调用的前后分别进行逻辑处理。
用GreetingProxy类实现了Greeting接口,并在构造方法中初始化了一个GreetingImpl实例。然后在GreetingProxy的sayHello方法中调用GreetingImpl的sayHello方法,并在调用的前后插入before和after方法,在这2个方法里实现前后的逻辑,达到我们的目的。
我们写一个main方法测试一下。
比写死代码优雅多了!但是有个问题就是,XxxProxy的类会越来越多,累死程序员!
JDK动态代理
一直用上面的代理模式开发,是否就有优越感了呢?肯定会被架构师骂的,会让你全部重构!其实上面的模式是“静态代理”,现在我们讲讲“动态代理”。
DynamicProxy中定义了一个Object类型的target变量,它是被代理的目标对象。通过构造函数初始化(即“注入”)。DynamicProxy实现了InvocationHandler接口,并实现了接口的invoke方法。在invoke方法中,通过java反射机制去调用注入对象的method,并在调用前后处理before和after逻辑。
写一个main方法,看怎么使用。
是不是更具有通用性?方法就是用这个通用的DynamicProxy类去包装GreetingImpl实例,然后调用JDK给我们提供的Proxy类的工厂方法newProxyInstance去动态的创建一个Greeting接口的代理类,最后调用这个代理类的sayHello方法。
Proxy.newProxyInstance的参数
参数1:ClassLoader
参数2:该实现类的所有接口
参数3:动态代理对象
代码可以进一步优化下,避免再次出现到处都是Proxy.newProxyInstance。
JDK动态代理好的地方是接口变了,动态代理类不用动。用静态代理,接口变了,实现类要动,代理类也要动。
CGlib动态代理
JDK动态代理有个缺点是必须代理有接口的类,没有任何接口的类就代理不了。这就要讲到CGlib动态代理了。
AOP技术简介
AOP(Aspect-Oriented Programming)面向切面编程。切面是什么?切面表示从业务逻辑分离出来的横切逻辑,比如性能监控、日志记录、权限控制,这些功能可从核心逻辑代码中抽离出去。也就是说AOP可以解决代码耦合问题,让职责更加单一。
Spring AOP
spring AOP包含:前置增强(before advice实现接口MethodBeforeAdvice)、后置增强(after advice实现接口AfterReturningAdvice)、环绕增强(around advice实现接口MethodInterceptor)、抛出增强、引入增强等。
环绕增强
也支持下面配置文件使用方式。
Spring AOP:切面
之前讲到的AOP框架可以理解为一个拦截器框架,但这个拦截器有点武断。它拦截了一个类,就拦截了这个类的所有方法。但我们只需要拦截特定的方法,不需要拦截所有方法。这就是切面要解决的问题。
切面将增强类和拦截匹配条件组合到一起,拦截匹配条件即切点(Pointcut)。Adivsor(切面)封装了Advice(增强)和Pointcut(切点)。
新增2个新方法。
interceptorNames不再是一个增强,而是一个切面。good.*表示匹配以good开头的方法。除了正则切面类RegexpMethodPointcutAdvisor,还支持其他切面类。
proxyTargetClass强制代理类。
Spring AOP:自动代理(扫描Bean名称)
optimize为ture。表示支持代理类:如果该类有接口就代理接口(使用JDK动态代理),如果该类没有接口就代理类(使用CGlib动态代理)。
CGlib创建代理的速度比较慢,但创建代理后运行的速度非常快,而JDK动态代理真好相反。所以建议在系统初始化的时候用CGlib去创建代理,并放入spring的ApplicationContext中以备后用。
上面例子只能匹配目标类,不能指定方法。spring AOP基于切面提供了自动代理生成器:DefaultAdvisorAutoProxyCreator。
这里无需配置代理,代理由DefaultAdvisorAutoProxyCreator自动生成。但不管怎么简化,解决不了切面的配置这个手工劳动。
Spring+AspectJ
集成AspectJ使用AspectJ的切点表达式。
基于注解:通过AspectJ execution表达式拦截方法
ProceedingJoinPoint称为连接点(JoinPoint),可以通过该对象获取方法任何信息。
execution(* aop.demo.GreetingImpl.*(..))
execution()表示拦截方法,括号中定义需要匹配的规则。
第一个“*”表示方法的返回值是任意的。
第二个“*”表示匹配该类中的所有方法。
(..)表示方法的参数是任意的。
为true即代理目标类,false只代理接口。
基于注解:通过AspectJ @annotation表达式拦截方法
基于配置
除了注解定义切面外,也支持配置文件定义切面类。
AOP思维导图
参考文献
参考:《架构探险 从零开始写javaweb框架》
。
。
精彩原创文章投稿有惊喜!
VSRC欢迎精品原创类文章投稿,优秀文章一旦采纳发布,将为您准备的丰富奖金税后1000元现金或等值礼品,上不封顶!如若是安全文章连载,奖金更加丰厚,税后10000元或等值礼品,上不封顶!可点击“阅读原文”了解规则。(最终奖励以文章质量为准。活动最终解释权归VSRC所有)
不知道,大家都喜欢阅读哪些类型的信息安全文章?
不知道,大家都希望我们更新关于哪些主题的干货?
现在起,只要您有任何想法或建议,欢迎直接回复本公众号留言!
精彩留言互动的热心用户,将有机会获得VSRC赠送的精美奖品一份!
同时,我们也会根据大家反馈的建议,选取热门话题,进行原创发布!
点击阅读原文进入 另为了挣到10000块,他在VSRC投了一篇稿!