一.Proxy
//抽象角色
public interface Rent {
public void rent();
}
//真实角色
public class Host implements Rent{
public void Rent() {
System.out.println("房东要出租房子了");
}
}
1.静态代理
//代理角色
public class Proxy implements Rent {
private Host host;
public Proxy(Host host) {
this.host = host;
}
public Proxy() {
}
public void rent() {
lookHose();
host.rent();
contract();
free();
}
//看房
public void lookHose() {
System.out.println("看房");
}
//签合同
public void contract() {
System.out.println("签合同");
}
//收取中介费
public void free() {
System.out.println("收取中介费");
}
}
//客户
public class Cilent {
public static void main(String[] args) {
//房东要租房子
Host host = new Host();
//中介代理帮租房子,但是一般会有一些会有一些附属操作
Proxy proxy = new Proxy(host);
//你不用面对房东,直接找中介租房即可
proxy.rent();
}
}
2.动态代理
//代理角色
public class ProxyInvocationHandle implements InvocationHandler {
//获取代理的接口
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成代理对象
public Object getProx(){
return
Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(rent,args);
}
}
//客户
public class client {
public static void main(String[] args) {
//真实角色
Host host = new Host();
//代理角色
ProxyInvocationHandle pri = new ProxyInvocationHandle();
//设置要代理的对象(真实类)
pri.setRent(host);
//动态生成代理类
Rent prox = (Rent) pri.getProx();
prox.Rent();
}
}
二.Aop
aop:面向切面编程,利用aop可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合性降低,提高程序的可重用性,同时提高了开发的效率
注:
- 横切关注点:跨越应用程序多个模块的方法或功能,即,与我们业务逻辑无关,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等
- 切面(aspect):横切关注点被模块化的特殊对象,即----一个类
- 通知(advice):切面必须要完成的工作。即----类中的一个方法
- 目标(target):被通知的对象
- 代理(Proxy):向目标对象引用通知之后创建的对象
- 切入点(pointcut):切面通知执行的“地点”的定义
- 连接点(jointPoint):与切入点匹配的执行点
Aop-eg:
//接口
public interface UserService {
public void add();
public void delete();
public void update();
public String select();
}
//实现类
@Component
public class UserServiceImpl implements UserService{
public void add() {
System.out.println("增加一条语句");
}
public void delete() {
System.out.println("删除一条语句");
}
public void update() {
System.out.println("更新一条语句");
}
public String select() {
System.out.println("查询一条语句");
return 2>3?"d":"c";
}
}
//增加业务
@Component
public class Div {
public void before(){
System.out.println("执行前");
}
public void after(){
System.out.println("执行后");
}
}
配置文件
<!--第三种方法 注解-->
<!--注解驱动-->
<aop:aspectj-autoproxy/>
<!--方式一:使用原生api接口-主要springAPI接口实现-->
<!--配置aop-->
<aop:config>
<!--切入点:expression:表达式,execution(要执行的位置!* * * * * *)-->
<aop:pointcut id="pointcut" expression="execution(* com.zh.service.UserServiceImpl.*(..))"/>
<!--执行环绕增加-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
<!--方法二:自定义实现aop(切面定义)-->
<aop:config>
<!--自定义切面,ref-要引用的类-->
<aop:aspect ref="div" >
<!--切入点-->
<aop:pointcut id="point" expression="execution(* com.zh.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:after method="after" pointcut-ref="point"/>
<aop:before method="before" pointcut-ref="point"/>
</aop:aspect>
</aop:config>