一、常规的applicationContext.xml配置
<?xml version="1.0" encoding="UTF8"?>
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd ">
<!-- 开启注解-->
<context:annotation-config/>
<!--导入spring-dao.xml-->
<import resource="spring-dao.xml"/>
<!-- Mapper对象 往下都是-->
这bean玩意可以在UserMapperImpl类上注解@Component就可以由Spring接管了
同时还有,注意其set方法上要用@Autowired来自动装配
<bean id="userMapperImpl" class="com.gy.mapper.UserMapperImpl" >
<!-- 构造器注入-->
<constructor-arg name="sqlSessionTemplate" ref="sqlSession"/>
<!-- set方法注入-->
<property name="sqlSessionTemplate" ref="sqlSession"/>
</bean>
</beans>
二、动态代理
(1)静态代理
1.静态代理没什么好说的就是一个真实对象(房东)就一个代理对象。
2.但是会有以下情况
3. 如果真实对象变多的时候,代理对象也跟着多起来(因为要实现同一个接口),代码量翻倍。
4.我们希望的是,更多的真实对象时候,我们只需实现真实对象的方法就好,而代理的代码则自动生成,减少开发成本。从此就出现了动态代理。
(2)JDK动态代理
使用原生代码实现,实质是反射机制。
package com.zp.demon01;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* InvocationHandler调用处理程序
* 写在前面:真实对象和代理对象都要实现/继承共同的规范(抽象类或接口),而真实对象只需要实现纯粹的方法即可
* 而代理对象可以做额外的任务,比如记录日志等。
*/
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//生成得到代理类并且实例化代理类
public Object getProxy(){
// this.getClass().getClassLoader()获取类加载器,类加载器属于jvm,只有获取到这个类加载器才能将代理类加载到jvm中。
// target.getClass().getInterfaces() 获取真实对象的实现的所有接口,为了创建代理类时,将这些接口都实现。
// 代理类反编译得到的方法中有一句:
// super.h.invoke(this, m4, (Object[])null);
// super表示调用的是父类(Proxy),h表示的是当前ProxyInvocationHandler类的对象,
// 目的为了通过super.h.invoke()调用Proxy子类的invoke(Object proxy, Method method, Object[] args)的方法。
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();//环绕前
Object result = method.invoke(target, args);
after();//环绕后
return result;
}
}
测试方法:
@org.junit.jupiter.api.Test
public void TestProxy(){
Host host = new Host();
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
proxyInvocationHandler.setTarget(host);
Rent proxy = (Rent) proxyInvocationHandler.getProxy();
proxy.rent();
}
(2)AOP方式一
导入jar包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
配置applicationContext.xml
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.zp.demon03.UserServiceImpl.* (..))"/>
begin与end为两个自定义类,分别实现了 MethodBeforeAdvice,AfterReturningAdvice接口
spring通过不同的接口来确定织入的通知执行的顺序
<aop:advisor advice-ref="begin" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="end" pointcut-ref="pointcut"/>
</aop:config>
当执行expression="execution(* com.zp.demon03.UserServiceImpl.* (..))指定的方法时,通知会自动的随之执行。
(3)AOP方式二
同样也导org.aspectj包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
配置applicationContext.xml
<aop:config>
与方式一相比多了这个<aop:aspect/>,diy是引用自定义的类,里面就写扩展的方法就行(before after)
<aop:aspect ref="diy">
<aop:pointcut id="point" expression="execution(* com.zp.demon03.UserServiceImpl.* (..))"/>
这两个方法都是通知,方法在自定义的diy类中,
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
三、spring整合mybatis
(1)编写spring-dao.xml文件 内容如下
都是写死的模板,直接套用就好,注意中括号的不同就好
<?xml version="1.0" encoding="UTF8"?>
<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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--使用spring数据源来替代mybatis的配置
这里使用了spring-jdbc的org.springframework.jdbc.datasource.DriverManagerDataSource
-->
<!-- 配置文件db.properties的导入-->
<context:property-placeholder location="【db.properties】"/>
<!-- 配置并连接数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.jdbcUrl}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</bean>
<!-- sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 绑定数据源-->
<property name="dataSource" ref="dataSource"/>
<!-- 绑定配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 扫描Mapper.xml文件-->
<property name="mapperLocations" value="classpath:【com/gy/mapper/*.xml】"/>
</bean>
<!-- SqlSessionTemplate(模板)其实就是sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
(2)MapperImpl实体类的使用
1.方式一
需要手动写sqlseesionTemplate属性并通过@Autowired自动装配获取。
有了sqlseesionTemplate直接.getMapper(接口.class)使用即可
package com.gy.mapper;
import ....
@Component
public class UserMapperImpl implements UserMapper{
//为了整合的区分 所以以后使用SqlSessionTemplate与sqlSession使用一样
private final SqlSessionTemplate sqlSessionTemplate;
//构造器
@Autowired
public UserMapperImpl(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionTemplate = sqlSessionTemplate;
}
@Override
public List<User> queryUser() {
UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
return mapper.queryUser();
}
}
2.方式二(偷懒)
继承SqlSessionDaoSupport类就可以直接通过getSession来使用
package com.gy.mapper;
import ....;
@Component
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
//因为sqlSessionFactory在父类是通过set方法注入的,
//但由于没办法给父类(只读)添加@Autowired来自动装配,所以只能重写父类方法,
//最后调用父类set方法
@Autowired
@Override
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
super.setSqlSessionFactory(sqlSessionFactory);
}
@Override
public List<User> queryUser() {
return getSqlSession().getMapper(UserMapper.class).queryUser();
}
}
四、Spring中的事务
(1)导包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
(2)配置spring-dao.xml
简单,直接将下面的代码,追加到上面的spring-dao.xml的末尾就可以开启事务了。
<!-- 配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 结合AOP实现事务的织入 别人已经写好这个通知,直接使用即可-->
<!-- 配置事务通知(增强)注意需要tx的命名空间-->
<tx:advice id="tx" transaction-manager="transactionManager">
<!-- 给哪些方法配置事务 是具体的方法名 或者 *表示所有方法都开启事务-->
<tx:attributes>
<!-- <tx:method name="add" propagation="REQUIRED"/>-->
<!-- <tx:method name="delete" propagation="REQUIRED"/>-->
<!-- <tx:method name="update" propagation="REQUIRED"/>-->
<!-- <tx:method name="queryUser" propagation="REQUIRED"/>-->
<tx:method name="*" propagation="REQUIRED"/>
<tx:method name="query" read-only="true"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入点-->
<aop:config>
<!--dao层 只是对单个数据表的操作,而事务管理的意思是,对多个数据表操作时,有的表成功了,有的没成功,可以促发回滚,所以是在service层 -->
<aop:pointcut id="txPoint" expression="【execution(* com.gy.service.*.* (..))】"/>
<!--测试事务是否成功时,应该在service层制造错误,而不是在controller层,因为事务织入的是service层-->
<aop:advisor advice-ref="tx" pointcut-ref="txPoint"/>
</aop:config>
五、所有jar包(pom.xml)
<?xml version="1.0" encoding="UTF8"?>
<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>org.example</groupId>
<artifactId>【spring-mybatis】</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<finalName>spring-mybatis</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins>
<!--必须配置,属于maven的一个bug,只有这样mapper.xml文件才能编译导出-->
<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>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.2</version>
<scope>test</scope>
</dependency>
<!--myBaits-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>