一. 使用xml文件进行增强
1.类关系图
?2.文件结构
用xml实现AOP时忽略SpringConfiguration类文件
类说明:
Account:持久层类,对标数据库Account表每条记录
AccounDaotImpl:持久层类,对Account进行简单操作,包含以下
/**
* 查询所有
* @return
*/
List<Account> findAllAccount();
/**
* 查询Id查询用户
* @return
*/
Account findAccountById(Integer accountId);
/**
* 根据名称查询账户
* @param accountName
* @return 有唯一结果就返回,没有结果就返回null
*/
Account findAccountByName(String accountName);
/**
* 保存
* @param account
*/
void saveAccount(Account account);
/**
* 更新
* @param account
*/
void updateAccount(Account account);
/**
*删除记录
* @param accountId
*/
void deleteAccount(Integer accountId);
AccounServiceImpl:业务层类,对记录进行一些高级操作,这些操作由AccountDaoImpl中的简单操作组合而成,此类中实现业务安全控制,即通过AOP增强对操作加入事务绑定。
ConnectionUtils:从数据源中获取一个连接,并和线程绑定,并提供移除线程操作(将线程放回线程池)
TransactionManager:事务管理类,包括开启事务、提交事务、回滚事务、释放连接操作。释放连接后将连接放回数据库连接池并调用ConnectionUtils中的deleteAccount方法将线程放回线程池。
beanFactory:切片类,类中调用TransactionManager对象中的事务相关方法对AccountServiceIpml中的操作进行增强。
3. xml配置
配置思路:
理清楚类之间的关系,根据类中调用的其他类对象进行bean的创建以及引用
<aop:config>注明切面类以及切面方法、被代理对象、被代理对象中的需要增强的方法。切入点表达式见:《Spring | 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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置AccountService-->
<bean id="accountService" class="com.alan.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<!--配置accountDao-->
<bean id="accountDao" class="com.alan.dao.impl.AccountImpl">
<property name="connectionUtils" ref="connectionUtils"></property>
<property name="runner" ref="runner"></property>
</bean>
<!--配置runner-->
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
</bean>
<!--配置beanFactory代理工厂-->
<bean id="beanFactory" class="com.alan.factory.beanFactory">
<property name="accountService" ref="accountService"></property>
<property name="txManager" ref="txManager"></property>
</bean>
<!--配置txManager事务管理器-->
<bean id="txManager" class="com.alan.utils.TransactionManager">
<property name="connectionUtils" ref="connectionUtils"></property>
</bean>
<!--配置connectionUtils连接工具-->
<bean id="connectionUtils" class="com.alan.utils.ConnectionUtils">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置dataSource数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db03"></property>
<property name="user" value="root"></property>
<property name="password" value="xiaoyahuan1997"></property>
</bean>
<!--配置切面-->
<aop:config>
<!--ref引用切面类-->
<aop:aspect id="beanAdvice" ref="beanFactory">
<aop:around method="aroundPrintLog" pointcut-ref="pt1"></aop:around>
<aop:pointcut id="pt1" expression="execution(*
com.alan.service.impl.AccountServiceImpl.*(..))"></aop:pointcut>
</aop:aspect>
</aop:config>
</beans>
?
二.使用注解进行AOP增强
1. 文件结构依然如上,配置文件xml中只保留了dataSource和QueryRunner的bean创建,因为这两个类是从jar包导入的,无法进行注解创建
bean.xml文件如下:
<?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:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置runner-->
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
<!--
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
此句可写可不写
-->
</bean>
<!--配置dataSource-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db03"></property>
<property name="user" value="root"></property>
<property name="password" value="xiaoyahuan1997"></property>
</bean>
<!--配置spring创建容器时要扫描的包-->
<context:component-scan base-package="com.alan"></context:component-scan>
<!--配置spring开启注解AOP的支持-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
其中,下面两句用来指定用注解进行bean的创建并配置spring开启注解AOP的支持
<!--配置spring创建容器时要扫描的包-->
<context:component-scan base-package="com.alan"></context:component-scan>
<!--配置spring开启注解AOP的支持-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
注:由注释进行对象注入时不用setter方法,而又xml文件进行对象注入时,每个(对象)属性都需要setter方法
2. 根据文件类间关系进行注释配置
ConnectionUtils类:
属性:
dataSource,由bean.xml文件进行创建并由@Autowired装入IOC容器
?TransactionManager类:
属性:
connetionUtils:注释创建并装入IOC容器
AccountDaoImpl类:
属性:
runner:由bean.xml文件进行创建,注释装入IOC容器
connectionUtils:注释创建并装入IOC容器
?AccountServiceImpl类:
属性:
accountDao:注释创建并加入IOC容器
?beanFactory类:
属性:
TransactionManager:注释创建并加入IOC容器
@Component("proxyService")
@Aspect//当前类是一个切面类
public class beanFactory {
@Pointcut("execution(* com.alan.service.impl.AccountServiceImpl.*(..))")
//切入点表达式
private void pt1(){};
@Autowired
private TransactionManager txManager;
/**
* 获取Service的代理对象
*/
@Around("pt1()")
public Object aroundPrintLog(ProceedingJoinPoint pjp) {
Object rtValue = null;
try {
Object[] args = pjp.getArgs();
txManager.beginTransaction();
rtValue = pjp.proceed(args);//明确调用切入点方法
txManager.commit();
return rtValue;
//返回代理对象
} catch (Throwable t) {
txManager.rollback();
throw new RuntimeException(t);
} finally {
txManager.release();
}
}
}
?3. 测试类
public class AccountServiceTest {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountService as = (IAccountService) ac.getBean("accountService");
as.transfer("aaa", "bbb" 100f);
}
}
三.将bean.xml文件替换为config.class文件
1.文件中进行runner和数据源dataSource配置
@Configuration//配置类
@ComponentScan(basePackages = "com.alan")//要扫描的包
public class SpringConfiguration {
/**
* 创建一个runner对象
* @param dataSource
* @return
*/
@Bean(name = "runner")//创建runner并加入IOC容器
public QueryRunner createQueryRunner(DataSource dataSource) {
return new QueryRunner(dataSource);
}
/**
* 创建数据源
* @return
*/
@Bean(name = "dataSource")
public DataSource createDataSource() {
try {
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass("com.mysql.jdbc.Driver");
ds.setJdbcUrl("jdbc:mysql://localhost:3306/db03");
ds.setUser("root");
ds.setPassword("xiaoyahuan1997");
return ds;
} catch (Exception e) {
throw new RuntimeException();
}
}
}
2. 测试类
public class AccountServiceTest {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
//无bean.xml需要创建AnnotationConfigApplicationContext()对象
//ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountService as = (IAccountService) ac.getBean("accountService");
as.transfer("aaa", "bbb", 100f);
}
}
完整代码见:
GitHub - AlanBiggerM/Java: Account project with .xml file as well as without file in AOPhttps://github.com/AlanBiggerM/Java
|