基于xml
- 配置pom.xml文件
- 构建业务代码
- 配置ApplicationContext.xml文件
1 pom.xml文件中需要添加的依赖
<!--spring-context.jar
这个jar 文件为Spring 核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI 所需的全部类,instrumentation组件以及校验Validation 方面的相关类。
外部依赖spring-beans, (spring-aop)。-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.3</version>
</dependency>
<!--C3P0的作用是获取数据库连接,对象为一个类型为DataSource的数据库连接池-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!--JAVA通过jdbc访问mySQL数据库时需要该包支持-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!--提供JdbcTemplate类-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.3</version>
</dependency>
<!--进行事物管理 提供相当于aop中Aspect的增强通知-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.3</version>
</dependency>
<!--是实现IOC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.3</version>
</dependency>
2 构建业务代码 :通过经典案例 转账来测试
2.1 dao层(持久层):DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此。
package com.lxh.dao.Impl;
import com.lxh.dao.AccountWage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* @author lxh
* @date 2021/1/17-22:12
*/
public class AccountWageImpl implements AccountWage {
// @Autowired (换做在 xml 文件中 set配置)
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void out(String outMan, int price) {
jdbcTemplate.update("update wage set price = price - ? where name = ?",price,outMan);
}
@Override
public void in(String inMan, int price) {
jdbcTemplate.update("update wage set price = price + ? where name = ?",price,inMan);
}
}
2.2 service层(服务层):Service层主要负责业务模块的逻辑应用设计。
package com.lxh.service.Impl;
import com.lxh.dao.AccountWage;
import com.lxh.service.AccountService;
/**
* @author lxh
* @date 2021/1/17-22:25
*/
public class AccountServiceImpl implements AccountService {
private AccountWage accountWage;
public void setAccountWage(AccountWage accountWage) {
this.accountWage = accountWage;
}
@Override
public void transfer(String outMan, String inMan, int price) {
accountWage.out(outMan,price);
int i = 1/0;
accountWage.in(inMan,price);
}
}
2.3 controller层(控制层):Controller层负责具体的业务模块流程的控制,在此层里面要调用Serice层的接口来控制业务流程。
package com.lxh.controller;
import com.lxh.dao.Impl.AccountWageImpl;
import com.lxh.service.AccountService;
import com.lxh.service.Impl.AccountServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author lxh
* @date 2021/1/17-22:28
*/
public class AccountController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("ApplicationContext.xml");
AccountService accountService = app.getBean(AccountService.class);
accountService.transfer("Jack","Lengwa",500);
}
}
3 配置ApplicationContext.xml文件
在我看来对于事物的管理思想就是AOP,而其中对于切点加强的通知是由Spring-tx来进行提供。在将这些通知织入到我们到加强的方法之前,还需要得配置平台事物管理器DataSourceTransactionManager
<?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: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
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!--加载properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置DataSource-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置模板-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="accountWage" class="com.lxh.dao.Impl.AccountWageImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<!--配置声明式事务控制-->
<!--目标对象 内部方法就是要增强的对象-->
<bean id="AccountService" class="com.lxh.service.Impl.AccountServiceImpl">
<property name="accountWage" ref="accountWage"></property>
</bean>
<!--配置平台事务管理器-->
<bean id="transaction" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--通知事务增强-->
<tx:advice id="txAdvice" transaction-manager="transaction">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--事务的织入-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.lxh.service.Impl.*.*(..))"></aop:advisor>
</aop:config>
</beans>
基于注解
- 同xml配置pom.xml(这里就不在展示)
- 构建业务代码(这里因为使用了注解因此会展示)
- 编写Configuration类(同xml中的ApplicationContext.xml文件作用相同)
1 pom.xml跳过
2 业务代码
2.1 dao 这里通过@Component将AccountWageImpl 实例化放入到Spring容器中
package com.lxh.dao.Impl;
import com.lxh.dao.AccountWage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
/**
* @author lxh
* @date 2021/1/17-22:12
*/
@Component("accountWage")
public class AccountWageImpl implements AccountWage {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void out(String outMan, int price) {
jdbcTemplate.update("update wage set price = price - ? where name = ?",price,outMan);
}
@Override
public void in(String inMan, int price) {
jdbcTemplate.update("update wage set price = price + ? where name = ?",price,inMan);
}
}
2.2 service 通过@Service将AccountServiceImpl 实例化到Spring容器中,同时@Autowired将,2.1 放到容器中的AccountWage 类型的 类注入到accountWage.
这也是Spring解耦合的一个体现。
package com.lxh.service.Impl;
import com.lxh.dao.AccountWage;
import com.lxh.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
/**
* @author lxh
* @date 2021/1/17-22:25
*/
@Service("AccountService")
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountWage accountWage;
@Override @Transactional(isolation = Isolation.DEFAULT)
public void transfer(String outMan, String inMan, int price) {
accountWage.out(outMan,price);
accountWage.in(inMan,price);
}
}
2.3 controller
public class AccountController {
public static void main(String[] args) {
ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfigure.class);
AccountService accountService = app.getBean(AccountService.class);
accountService.transfer("Jack","Lengwa",500);
}
}
3 Configuration类的配置
说明:这里对于jdbcTemplate和事物管理器都要用DataSource,
因此先对Datasource先进行配置。
@EnableTransactionManagement 等价于 <tx:annotation-driven transaction-manager="" />
package com.lxh.ApplicationContext;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
/**
* @author lxh
* @date 2021/1/17-23:26
*/
@Configuration
@ComponentScan("com.lxh")
//@Import({DataSourceConfigure.class,TransactionManagerConfigure.class,JdbcTemplateConfiguration.class})
@PropertySource("classpath:jdbc.properties")
@EnableTransactionManagement
public class SpringConfigure {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String name;
@Value("${jdbc.password}")
private String password;
@Bean(name = "dataSource")
public DataSource getdataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(name);
dataSource.setPassword(password);
return dataSource;
}
@Bean(name = "TransactionManager")
public DataSourceTransactionManager transactionManager() throws PropertyVetoException {
return new DataSourceTransactionManager(getdataSource());
}
@Bean(name = "jdbcTemplate")
public JdbcTemplate getJdbcTemplate() throws PropertyVetoException {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(getdataSource());
return jdbcTemplate;
}
}
补充:
关于jdbc.properties文件
位置:在resources目录下
内容:
jdbc.driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/XXXXX
jdbc.username = root
jdbc.password = XXXXXX