11.AOP
11.1简介
AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
11.2AOP在Spring中作用
提供声明式事务:允许用户自定义切面
-
横切关注点:跨越应用程序多个模块、与业务逻辑无关但需关注的方法或功能,如日志、安全、缓存、事务等。
-
切面(ASPECT):横切关注点被模块化的特殊对象,是一个类 。
-
通知(Advice):切面必须完成的工作,是类中的一个方法 。
-
目标(Target):被通知对象 。
-
代理(Proxy):向目标对象应用通知之后创建的对象 。
-
切入点(PointCut):切面通知执行 “地点” 的定义 。
-
连接点(JointPoint):与切入点匹配的执行点 。
11.3使用Spring实现AOP
需要一个依赖包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.24</version> <scope>runtime</scope> </dependency>
方法一:使用Spring的API接口
主要SpringAPI接口实现
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 注册bean--> <bean id="userService" class="com.lyj.service.UserServiceImpl"/> <bean id="log" class="com.lyj.log.Log"/> <bean id="afterLog" class="com.lyj.log.AfterLog"/> <!-- 方式一:使用原生Spring API接口--> <!--配置AOP 需要导入AOP的约束--> <aop:config> <!-- 切入点; expression表达式 execution(要执行的位置)--> <aop:pointcut id="pointcut" expression="execution(* com.lyj.service.UserServiceImpl.*(..))"/> <!-- 执行环绕增加--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> </beans>
方式二:自定义来实现AOP
主要是切面定义
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 注册bean--> <bean id="userService" class="com.lyj.service.UserServiceImpl"/> <bean id="log" class="com.lyj.log.Log"/> <bean id="afterLog" class="com.lyj.log.AfterLog"/> <!-- 方式二:自定义来实现AOP--> <bean id="diy" class="com.lyj.diy.DiyPointCut"/> <aop:config> <!-- 自定义切面 ref 要引用的类--> <aop:aspect ref="diy"> <!-- 切入点--> <aop:pointcut id="point" expression="execution(* com.lyj.service.UserServiceImpl.*(..))"/> <!-- 通知--> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config> </beans>
方式三:使用注解实现
package com.lyj.diy; //方式三:使用注解方式实现AOP import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect//标注这个类是一个切面 public class AnnotationPointCut { @Before("execution(* com.lyj.service.UserServiceImpl.*(..))") public void before(){ System.out.println("before"); } @After("execution(* com.lyj.service.UserServiceImpl.*(..))") public void after(){ System.out.println("after"); } @Around("execution(* com.lyj.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("环绕前"); Object proceed = joinPoint.proceed(); System.out.println("环绕后"); } }
12.整合Mybatis
12.1
pom.xml依赖包
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.example</groupId> <artifactId>Spring</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>Spring10-mybatis</artifactId> <packaging>war</packaging> <name>Spring10-mybatis Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <!-- <scope>test</scope>--> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.19</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>6.2.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>6.2.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.24</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>3.0.5</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.38</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> </dependencies> <!--在build中配置resources,来防止我们资源导出失败的问题--> <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project>
1.新建一个实体类
package com.lyj.pojo; import lombok.Data; @Data public class User { private int id; private String name; private String pwd; }
2.编写mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 类型别名配置 --> <typeAliases> <package name="com.lyj.pojo"/> <!-- 扫描整个包,别名默认为类名小写(如 User → user) --> </typeAliases> <!-- 环境配置(数据库连接) --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!-- 注册 Mapper 映射文件 --> <mappers> <mapper class="com.lyj.mapper.UserMapper"/> </mappers> </configuration>
3.编写接口
package com.lyj.mapper; import com.lyj.pojo.User; import java.util.List; public interface UserMapper { public List<User> selectUser(); }
4.编写接口对应的xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace= 绑定一个对应的Dao/Mapper接口--> <mapper namespace="com.lyj.mapper.UserMapper"> <select id="selectUser" resultType="user"> select * from mybatis.user; </select> </mapper>
5.在mybatis-config.xml注册接口
<!-- 注册 Mapper 映射文件 --> <mappers> <mapper class="com.lyj.mapper.UserMapper"/> </mappers>
6.测试
import com.lyj.mapper.UserMapper; import com.lyj.pojo.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; public class MyTest { @Test public void test() throws IOException{ String resources = "mybatis-config.xml"; InputStream in = Resources.getResourceAsStream(resources); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in); SqlSession session = sessionFactory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class); List<User> userList = mapper.selectUser(); for (User user : userList) { System.out.println(user); } } }
12.2 Mybatis-Spring
方式一
1.编写数据源
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--DataSource:使用Spring的数据源替换Mybatis的配置 c3p0 dbcp druid--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC&characterEncoding=UTF8"/> <property name="username" value="root"/> <property name="password" value="123456"/> <!-- 替代了mybatis-config.xml中的--> <!-- 环境配置(数据库连接) --> <!--<environments default="development">--> <!-- <environment id="development">--> <!-- <transactionManager type="JDBC"/>--> <!-- <dataSource type="POOLED">--> <!-- <property name="driver" value="com.mysql.cj.jdbc.Driver"/>--> <!-- <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC"/>--> <!-- <property name="username" value="root"/>--> <!-- <property name="password" value="123456"/>--> <!-- </dataSource>--> <!-- </environment>--> <!--</environments>--> </bean> <!-- sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 绑定Mybatis配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/lyj/mapper/UserMapper.xml"/> <!-- 替代了mybatis-config.xml中的--> <!-- 注册 Mapper 映射文件 --> <!--<mappers>--> <!-- <mapper class="com.lyj.mapper.UserMapper"/>--> <!--</mappers>--> </bean> <!-- SqlSessionTemplate: 就是sqlSession--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!-- 只能使用构造器注入sqlSessionFactory, 业务没有set方法--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean> <!-- <bean id="userMapperImpl" class="com.lyj.mapper.UserMapperImpl">--> <!-- <property name="sqlSessionTemplate" ref="sqlSession"/>--> <!-- </bean>--> </beans>
2.sqlSessionFactory
3.sqlSessionTemplate
4.需要给接口加实现类
5.将自己些的实现类,注入到Spring中
6.测试使用
import com.lyj.mapper.UserMapper; import com.lyj.pojo.User; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper userMapper = context.getBean("userMapperImpl",UserMapper.class); for(User user:userMapper.selectUser()){ System.out.println(user); } } }
方式二
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--DataSource:使用Spring的数据源替换Mybatis的配置 c3p0 dbcp druid--> <import resource="spring-dao.xml"/> <bean id="userMapperImpl" class="com.lyj.mapper.UserMapperImpl"> <property name="sqlSessionTemplate" ref="sqlSession"/> </bean> ========方式二============================== <bean id="userMapperImpl2" class="com.lyj.mapper.UserMapperImpl2"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> </beans>