代理模式
代理模式的两个设计原则:
-
代理类 与 委托类 具有相似的行为(共同)
-
代理类增强委托类的行为
代理的三要素
a、有共同的行为 - 接口
b、目标角色 - 实现行为
c、代理角色 - 实现行为 增强目标对象行为
静态代理
特点
1、目标角色固定
2、在应用程序执行前就得到目标角色
3、代理对象会增强目标对象的行为
4、有可能存在多个代理 引起"类爆炸"(缺点)
示例
接口
package com.yxh.service;
public interface CrudService {
void insert();
void delete();
void update();
void selectAll();
}
委托类
package com.yxh.service;
public class CrudServiceImpl implements CrudService{
@Override
public void insert() {
System.out.println("增加");
}
@Override
public void delete() {
System.out.println("删除");
}
@Override
public void update() {
System.out.println("修改");
}
@Override
public void selectAll() {
System.out.println("查询所有");
}
}
静态代理
package com.yxh.service;
public class CrudServiceImplProxy implements CrudService{
private CrudServiceImpl csipl = new CrudServiceImpl();
@Override
public void insert() {
System.out.println("开启事务");
csipl.insert();
System.out.println("提交事务");
}
@Override
public void delete() {
System.out.println("开启事务");
csipl.delete();
System.out.println("提交事务");
}
@Override
public void update() {
System.out.println("开启事务");
csipl.update();
System.out.println("提交事务");
}
@Override
public void selectAll() {
csipl.selectAll();
}
}
动态代理
相比于静态代理,动态代理在创建代理对象上更加的灵活,动态代理类的字节码在程序运行时,由Java反射机制动态产生。它会根据需要,通过反射机制在程序运行期,动态的为目标对象创建代理对象,无需程序员手动编写它的源代码。动态代理不仅简化了编程工作,而且提高了软件系统的可扩展性,因为反射机制可以生成任意类型的动态代理类。代理的行为可以代理多个方法,即满足生产需要的同时又达到代码通用的目的。
动态代理的两种实现方式:
-
JDK 动态代理
-
CGLIB动态代理
特点
- 目标对象不固定
- 在应用程序执行时动态创建目标对象
- 代理对象会增强目标对象的行为
示例:
package com.yxh.service;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class GetCrudServiceImplProxy {
public static CrudService getProxyClass(){
CrudService cs = (CrudService) Proxy.newProxyInstance(GetCrudServiceImplProxy.class.getClassLoader(), new Class[]{CrudService.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
CrudServiceImpl crudService = new CrudServiceImpl();
String name = method.getName();
if (name.contains("selectAll")) {
method.invoke(crudService);
}else {
System.out.println("事务开始");
method.invoke(crudService);
System.out.println("事务提交");
}
return null;
}
});
return cs;
}
}
SpringAop
AOP简介和作用
- AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构。
- OOP(Object Oriented Programming)面向对象编程。
- 作用:简单的说就是在不改变方法源代码的基础上对方法进行功能增强。
- Spring理念:无入侵式/无侵入式
- 连接点(JoinPoint):正在执行的方法,例如:update()、delete()、select()等都是连接点。
- 切入点(Pointcut):进行功能增强了的方法,例如:update()、delete()方法,select()方法没有被增强所以不是切入点,但是是连接点。
- 在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法
- 一个具体方法:com.tyhxzy.dao包下的BookDao接口中的无形参无返回值的save方法
- 匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法
- 在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法
- 通知(Advice):在切入点前后执行的操作,也就是增强的共性功能
- 在SpringAOP中,功能最终以方法的形式呈现
- 通知类:通知方法所在的类叫做通知类
- 切面(Aspect):描述通知与切入点的对应关系,也就是哪些通知方法对应哪些切入点方法。
AOP的真正目的
AOP真正目的是:你写代码的时候,只需考虑主流程,而不用考虑那些不重要的,但又必须要写的其它相同的代码,这些其它的相同代码所在的类就是切面类。
主要应用场景:
1.事务处理
2.日志记录
3.用户权限
AOP入门案例
配置文件实现
【第一步】导入aop相关坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tyhxzy</groupId>
<artifactId>spring005_0602</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--junit的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--spring核心依赖,会将spring-aop传递进来-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!--切入点表达式依赖,目的是找到切入点方法,也就是找到要增强的方法-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!-- spring整合junit包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
接口
package com.yxh.service;
public interface CrudService {
void add();
void selectAll();
void update();
void delete();
}
实现类
package com.yxh.service;
public class CrudServiceImpl implements CrudService{
@Override
public void add() {
System.out.println("add");
}
@Override
public void selectAll() {
System.out.println("selectAll");
}
@Override
public void update() {
System.out.println("update");
}
@Override
public void delete() {
System.out.println("delete");
}
}
通知类
package com.yxh.util;
public class TrancationAdvice {
public void start(){
System.out.println("start advice---");
}
public void end(){
System.out.println("end advice---");
}
}
spring配置配置文件applicationContent.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">
<bean id="cs" class="com.yxh.service.CrudServiceImpl">
</bean>
<bean id="ta" class="com.yxh.util.TrancationAdvice">
</bean>
<aop:config>
<aop:pointcut id="ptc" expression="execution(void com.yxh.service.CrudServiceImpl.*())"/>
<aop:aspect id="aspc" ref="ta">
<aop:before method="start" pointcut-ref="ptc"/>
<aop:after method="end" pointcut-ref="ptc"/>
</aop:aspect>
</aop:config>
</beans>
测试类
package com.yxh;
import com.yxh.service.CrudService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@ContextConfiguration(locations = "classpath:applicationContent.xml")
public class AopTest {
@Autowired
private CrudService crudService;
@Test
public void testAop(){
crudService.delete();
}
}
标签:Spring,void,System,代理,Aop,println,public,out
From: https://www.cnblogs.com/YxinHaaa/p/17456961.html