文章目录
一.Bean元素的继承
BaseDAO公共的DAO
@ToString
public abstract class BaseDAO {
//模拟一个连接池
@Setter
protected String dataSource;
}
DepartmentDAOImpl类
@Setter
public class DepartmentDAOImpl extends BaseDAO{
@Override
public String toString() {
super.toString();
return "DepartmentDAO ["+dataSource+"]";
}
}
EmployeeDAOImpl
@Setter
public class EmployeeDAOImpl extends BaseDAO{
@Override
public String toString() {
super.toString();
return "EmployeeDAOImpl ["+dataSource+"]";
}
}
App-context.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="baseDAO" abstract="true" class="cn.dusk._1_extends.BaseDAO">
<property name="dataSource" value="druid"/>
</bean>
<bean id="employeeDAO" class="cn.dusk._1_extends.EmployeeDAOImpl"
parent="baseDAO"/>
<bean id="DepartmentDAO" class="cn.dusk._1_extends.DepartmentDAOImpl"
parent="baseDAO"/>
</beans>
测试类App
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class App {
@Autowired
private EmployeeDAOImpl e;
@Autowired
private DepartmentDAOImpl d;
@Test
public void test() throws Exception {
System.out.println(e);
System.out.println(d);
}
}
二.注解注入
Autowired和Qualifier标签:
- 通过@Autowired标签可以让Spring自动的把属性需要的对象从Spring容器找出来,并注入给该属性。
- 第三方程序:Spring3.0之前,需要手动配置@Autowired解析注解程序,Spring就会自动的加入针对@Autowired标签的解析程序。从Spring3.0开始,可以不再需要改配置了。如果不在Spring的测试环境中,也找到@Autowired的解析代码,此时也必须配置.
<context:annotation-config/>
- @Autowired标签贴在字段或者setter方法上。
- @Autowired可以同时为一个属性注入多个对象。
public void setXxx(OtherBean1 other1,OtherBean2 other2) {}
- 使用@Autowired标签可以注入Spring内置的重要对象,比如BeanFactory,ApplicationContext。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringTest {
@Autowired
private ApplicationContext ctx;
}
- 默认情况下@Autowired标签必须要能找到对应的对象,否则报错。不过,可使用required=false来避免该问题:@Autowired(required=false)
- @Autowired找bean的方式:
- 首先按照依赖对象的类型找,如果找到则使用setter方法或者字段直接注入;
- 如果在Spring上下文中找到多个匹配的类型,再按照名字去找,如果没有匹配则报错;
- 可以通过使用@Qualifier(“otherBean”)标签来规定依赖对象按照bean的id+类型去找;
@Resource(name="otherBean2")
private OtherBean2 other2;
等价于
@Autowired
@Qualifier("otherBean2")
private OtherBean2 other2;
@Autowired VS @Resource: 都是只能注入符合类型
1. @Autowired:是Spring定义的标签,所以不太稳定,并且对象和spring框架关联(Spring对我们的代码有侵入);
2. @Resouce:是J2EE的规范,所以稳定,在J2EE规范容器中也能正常使用;
三.使用注解简化IoC
使用标签简化IoC:
-
使用标签来完成IoC,就必须有IoC标签的解析器:
使用context:component-scan来扫描spring需要管理的bean
base-package就告诉spring,去哪些包及其子包里去扫描bean,如果有多个包需要被扫描;只需要用逗号隔开多个包即可<context:component-scan base-package="com.dusk.oa.dao,cn.com.dusk.service" />
-
标注Bean的注解:@Component
默认情况,直接使用类的名字(首字母小写作为bean的名字)
如果要修改bean的名称;直接使用value属性来重新定义bean的名称@Component("otherbean") public class OtherBean {}
-
使用@Component的限制:
- 不能运用到静态工厂方法和实例工厂方法,但是可以使用到FactoryBean;
- 对于没有源代码的类(框架内部的预定义类),只能用XML配置;
-
bean组件版型标签
bean组件版型:@Service用于标注业务层组件、 @Controller用于标注控制层组件(如struts中的action) @Repository用于标注数据访问组件,即DAO组件。 @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
-
指定bean的作用域:@Scope(“prototype”)
-
初始化和销毁方法
@PostConstruct public void init() { 相当于<bean init-method="init" /> @PreDestroy public void destory() { 相当于<bean destroy-method="destory" />
-
选用xml还是注解:
1). Annotation:使用方便,XML文件很小,但是,依赖关系又重新回到了代码当中;
2). XML:使用稍微复杂,但是,代码很干净,代码不会跟任何框架产生关系;XML安全;
两种方式都必须掌握;(不是你写类和AOP必须使用XML配置,其他使用注解)
配置文件app-context.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: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">
<!--ioc解析器:组件扫描器 -->
<context:component-scan base-package="cn.dusk._3_ioc_anno"/>
<!-- 自动DI解析器 -->
<context:annotation-config/>
</beans>
OtherBean类
@Component
public class OtherBean {
}
SomeBean类
@ToString
@Component("beanSome")
public class SomeBean {
@Resource
private OtherBean other1;
public SomeBean() {
System.out.println("创建对象");
}
public void work() {
System.out.println("SomeBean.work");
}
@PostConstruct
public void init() {
System.out.println("对象初始化");
}
@PreDestroy
public void destroy() {
System.out.println("对象销毁");
}
}
App测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class App {
@Autowired
private SomeBean someBean;
@Test
public void test() throws Exception {
someBean.work();
}
}
四.综合案例使用注解
项目结构
UserAction类
@Controller
@Scope("prototype")
public class UserAction {
@Autowired
private IUserService service;
public String regist() {
service.regist(new User("zhen,ji"));
return "success";
}
}
IUserDAO接口
public interface IUserDAO {
void save(User user);
}
UserDAOImpl实现类
@Repository
public class UserDAOImpl implements IUserDAO{
public void save(User user) {
System.out.println("保存一个用户"+user);
}
}
实体类
@Setter@Getter@ToString
@AllArgsConstructor
public class User {
private String name;
}
接口IUserService
public interface IUserService {
void regist(User u);
}
实现类UserServiceImpl
@Service
public class UserServiceImpl implements IUserService{
@Autowired
private IUserDAO dao;
public void regist(User u) {
dao.save(u);
}
}
测试类App
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class App {
@Autowired
private UserAction action;
@Test
public void testRegist() throws Exception {
action.regist();
}
}
配置文件App-context.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: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">
<!-- 配置自动装配解析器 -->
<context:annotation-config/>
<!-- 组件扫描解析器 -->
<context:component-scan base-package="cn.dusk._4_regist_anno"/>
</beans>
五.装饰设计模式
装饰设计模式:在不必改变源代码基础上,动态地扩展一个对象的功能。
它是通过创建一个包装对象,也就是包裹真实的对象。
说的直白点,就是对已有对象进行功能增强!
得定义一个类(Service的包装类):
目的:增强ServiceImpl中的save和update方法.
做什么增强:
1. 在调用save方法之前:开启事务:
2. 正常调用完save方法之后:提交事务:
3. 如果调用save方法出现异常:回滚事务:
TransactionManager事务
//事务管理器,作用各种数据库的事务
public class TransactionManager {
public void begin() {
System.out.println("开始事务");
}
public void commit() {
System.out.println("提交事务");
}
public void rollback() {
System.out.println("回滚事务");
}
public Object allInOne(ProceedingJoinPoint point) {
Object res = null;
try {
//开始事务
begin();
//业务方法
res = point.proceed();
//提交事务
commit();
} catch (Throwable e) {
//回滚事务
rollback();
}
return res;
}
}
IUserService接口
public interface IUserService {
void save();
void update();
}
实现类UserServiceImpl
@Service
public class UserServiceImpl implements IUserService{
public void save() {
System.out.println("保存一个对象 ");
}
public void update() {
System.out.println("更新 一个对象");
}
}
UserServiceMarpper装饰类
public class UserServiceMarpper implements IUserService{
private IUserService targer;
private TransactionManager tm;
public UserServiceMarpper(IUserService targer, TransactionManager tm) {
this.targer = targer;
this.tm = tm;
}
public void save() {
try {
tm.begin();
targer.save();
tm.commit();
}catch(Exception e) {
tm.rollback();
}
}
public void update() {
try {
tm.begin();
System.out.println(1/0);
targer.update();
tm.commit();
}catch(Exception e) {
tm.rollback();
}
}
}
配置文件App-context.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: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">
<!-- 配置自动装配解析器 -->
<context:annotation-config/>
<!-- 组件扫描解析器 -->
<context:component-scan base-package="cn.dusk._5_aop.warpper"/>
</beans>
测试类App
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class App {
TransactionManager tm = new TransactionManager();
IUserService targer = new UserServiceImpl();
@Test
public void testWarpper() throws Exception {
UserServiceMarpper usm = new UserServiceMarpper(targer, tm);
usm.save();
usm.update();
}
}
六.静态代理
-
静态代理(proxy):在程序运行前就已经存在代理类的字节码文件,代理对象和真实对象的关系在程序运行前就确定了。
-
优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性。
-
缺点:
- 代理对象的某个接口只服务于某一种类型的对象,也就是说每一个真实对象都得创建一个代理对象。
- 如果需要代理的方法很多,则要为每一种方法都进行代理处理。
- 如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
UserServiceProxy代理类
@Component
public class UserServiceProxy implements IUserService{
@Setter
private IUserService us;
@Setter
private TransactionManager tm;
public void save() {
try {
tm.begin();
us.save();
tm.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
public void update() {
try {
tm.begin();
us.update();
System.out.println(1/0);
tm.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
app-cntext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!-- 配置自动装配解析器 -->
<context:annotation-config/>
<!-- 组件扫描解析器 -->
<context:component-scan base-package="cn.dusk._5_aop.static_proxy"/>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="cn.dusk._5_aop.TransactionManager"/>
<bean id="userServiceProxy" class="cn.dusk._5_aop.static_proxy.UserServiceProxy">
<property name="tm" ref="transactionManager"/>
<property name="us">
<bean class="cn.dusk._5_aop.warpper.service.impl.UserServiceImpl"/>
</property>
</bean>
</beans>
App测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class App {
@Autowired
private UserServiceProxy proxy;
@Test
public void testSave() throws Exception {
proxy.save();
}
@Test
public void testUpdate() throws Exception {
proxy.update();
}
}
七.JDK动态代理和CGLIB动态代理
动态代理类是在程序运行期间由JVM通过反射等机制动态的生成的,所以不存在代理类的字节码文件。代理对象和真实对象的关系是在程序运行事情才确定的。
JDK动态代理API分析:(只能对接口进行代理)
- java.lang.reflect.Proxy 类:
Java 动态代理机制生成的所有动态代理类的父类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。
主要方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler hanlder)
方法职责:为指定类加载器、一组接口及调用处理器生成动态代理类实例
参数:
loader :类加载器
interfaces :模拟的接口
hanlder :代理执行处理器
返回:动态生成的代理对象
- java.lang.reflect.InvocationHandler接口:
public Object invoke(Object proxy, Method method, Object[] args)
方法职责:负责集中处理动态代理类上的所有方法调用
参数:
proxy :生成的代理对象
method :当前调用的真实方法对象
args :当前调用方法的实参
返回: 真实方法的返回结果
- jdk动态代理操作步骤
1.实现InvocationHandler接口,创建自己增强代码的处理器。
2. 给Proxy类提供ClassLoader对象和代理接口类型数组,创建动态代理对象。
3. 在处理器中实现增强操作。
JdkProxyhandler代理类
@SuppressWarnings("all")
@Component
public class JdkProxyhandler implements InvocationHandler{
@Setter
private Object target;//目标对象
@Setter
private TransactionManager txManager;//事务管理
//获取代理对象
public <T>T getInstance(){
return (T)Proxy.newProxyInstance(
JdkProxyhandler.class.getClassLoader(),//类加载器
target.getClass().getInterfaces(),//对哪些接口做代理
this);//方法处理,(如何增强)
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res = null;
try {
txManager.begin();//开始事务
res = method.invoke(target, args);//业务操作
System.out.println(1/0);
txManager.commit();//提交事务
} catch (Exception e) {
txManager.rollback();
e.printStackTrace();
}
return res;
}
}
CGLIB动态代理:
原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
CglibCallback代理类
@SuppressWarnings("all")
//InvocationHandler有两个需要的是Spring里面的那个
public class CglibCallback implements InvocationHandler{
@Setter
private Object target;//真实类型
@Setter
private TransactionManager txManager;//事务管理器
//创建代理对象
public <T>T getInstance(){
Enhancer en = new Enhancer();
en.setSuperclass(UserServiceImpl.class);
en.setCallback(this);
return (T)en.create();
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res = null;
try {
txManager.begin();//开始事务
res = method.invoke(target, args);//业务操作
System.out.println(1/0);
txManager.commit();//提交事务
} catch (Exception e) {
e.printStackTrace();//回滚事务
txManager.rollback();
}
return res;
}
}
app-context.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: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">
<!-- 配置自动装配解析器 -->
<context:annotation-config/>
<!-- 组件扫描解析器 -->
<context:component-scan base-package="cn.dusk._5_aop.warpper"/>
<!-- 配置动态代理处理器 -->
<bean id="transactionManager" class="cn.dusk._5_aop.TransactionManager"/>
<bean id="jdkProxyhandler" class="cn.dusk._5_aop.dy_proxy.JdkProxyhandler">
<property name="target">
<bean class="cn.dusk._5_aop.warpper.service.impl.UserServiceImpl"/>
</property>
<property name="txManager" ref="transactionManager"/>
</bean>
<bean id="cglibCallback" class="cn.dusk._5_aop.dy_proxy.CglibCallback">
<property name="txManager" ref="transactionManager"/>
<property name="target">
<bean class="cn.dusk._5_aop.warpper.service.impl.UserServiceImpl"/>
</property>
</bean>
</beans>
测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class App {
@Autowired
private JdkProxyhandler hander;
@Autowired
private CglibCallback callback;
@Test
public void teestCglibSave() throws Exception {
//获取动态代理对象
UserServiceImpl proxy = callback.getInstance();
System.out.println("真实类型" + proxy.getClass());
proxy.save();
}
@Test
public void testCglibUpdate() throws Exception {
//获取动态代理对象
UserServiceImpl proxy = callback.getInstance();
proxy.update();
}
@Test
public void testSave() throws Exception {
//获取到动态代理对象
IUserService proxy = hander.getInstance();
//
System.out.println(proxy.getClass());
proxy.save();
}
@Test
public void testUpdate() throws Exception {
IUserService proxy = hander.getInstance();
proxy.update();
}
}
八.AOP概念
-
AOP的目的:
AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,
便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
说人话:把业务方法中与业务无关的操作抽离到不同的对象的方法中,最后使用动态代理的方式组合起来 -
AOP的优势:
降低模块的耦合度、使系统容易扩展、更好的代码复用性.
Spring的AOP使用动态代理实现:
如果一个类实现了接口,那么spring就使用JDK的动态代理完成AOP;
如果一个类没有实现接口,那么spring就是用cglib完成AOP; -
AOP当中的概念:
- 切入点(Pointcut):在哪些类,哪些方法上切入(where);
- 增强(Advice): 早期翻译为通知,在方法执行的什么时机(when:方法前/方法后/方法前后)做什么(what:增强的功能);
- 切面(Aspect): 切面=切入点+增强,通俗点就是:在什么时机,什么地点,做什么增强!
- 织入(Weaving): 把切面加入到对象,并创建出代理对象的过程。(该过程由Spring来完成)。
九.AOP的XML配置
AOP的规范本应该由SUN公司提出,但是被AOP联盟捷足先登.AOP联盟制定AOP规范
首先就要解决一个问题,怎么表示在哪些方法上增强—— AspectJ(语言)。
AspectJ切入点语法如下(表示在哪些包下的哪些类的哪些方法上做切入):
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
翻译成中文:
execution(<修饰符>? <返回类型> <声明类型>? <方法名>(<参数>) <异常>?)
Class类中的forName方法的完整签名:
public static java.lang.Class java.lang.Class.forName(String className) throws ClassNotFoundException
在所有的业务层方法上做增强:
execution(* com.dusk.pss.service.Service.(…))
Spring配置AOP的准备工作
- 引入Spring AOP开发依赖的jar包:
spring-aop-4.2.4.RELEASE.jar
aopalliance-1.0.0.jar
aspectjweaver-1.8.7.jar - 配置aop名称空间:
<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"><!--这里-->
<aop:config>
where:在哪做增强
<aop:pointcut expression="execution(* cn.dusk._6_aop.service.*Service.*(..))" id="pc"/>
what:做怎么增强
<aop:aspect ref="txManager">
when:在什么时机做增强
aop:before:在目标方法调用前做增强
<aop:before method="begin" pointcut-ref="pc"/>
aop:after-returning:方法正常结束时做后置增强
<aop:after method="commit" pointcut-ref="pc"/>
aop:after-throwing:方式异常结束时做后置增强
<aop:after-throwing method="rollback" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
十.Spring中的各种增强
各种不同的增强:
aop:before(前置增强):在方法执行之前执行增强;
aop:after-returning(后置增强):在方法正常执行完成之后执行增强(中间没有遇到任何异常);
aop:after-throwing(异常增强):在方法抛出异常退出时执行增强代码;
aop:after(最终增强):在方法执行之后执行,相当于在finally里面执行;可以通过配置throwing来获得拦截到的异常信息
aop:around(环绕增强):最强大的一种增强类型。 环绕增强可以在方法调用前后完成自定义的行为,环绕通知有两个要求,
1,方法必须要返回一个Object(返回的结果)
2,方法的第一个参数必须是ProceedingJoinPoint(可以继续向下传递的切入点)
接口IUserService
public interface IUserService {
void save();
void update();
}
UserServiceImpl实现类
@Service
public class UserServiceImpl implements IUserService{
public void save() {
System.out.println("保存一个对象 ");
}
public void update() {
System.out.println(1/0);
System.out.println("更新 一个对象");
}
}
配置App-context.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">
<!-- 配置自动装配解析器 -->
<context:annotation-config/>
<!-- 组件扫描解析器 -->
<context:component-scan base-package="cn.dusk._6_aop"/>
<!-- 配置事务管理器 -->
<bean id="txManager" class="cn.dusk._5_solvt.TransactionManager"/>
<bean id="userServiceImpl" class="cn.dusk._6_aop.service.impl.UserServiceImpl"></bean>
<aop:config>
<!-- 在哪里做增强 -->
<aop:pointcut expression="execution(* cn.dusk._6_aop.service.*Service.*(..)))" id="all"/>
<!-- 做什么增强 -->
<aop:aspect ref="txManager">
<!-- 在什么时机做增强 -->
<!-- aop:around:环绕增强 -->
<aop:around method="allInOne" pointcut-ref="all"/>
</aop:aspect>
</aop:config>
<!-- AOP配置:3w what/where/when
<aop:config>
where:在哪做增强
<aop:pointcut expression="execution(* cn.dusk._6_aop.service.*Service.*(..))" id="pc"/>
what:做怎么增强
<aop:aspect ref="txManager">
when:在什么时机做增强
aop:before:在目标方法调用前做增强
<aop:before method="begin" pointcut-ref="pc"/>
aop:after-returning:方法正常结束时做后置增强
<aop:after method="commit" pointcut-ref="pc"/>
aop:after-throwing:方式异常结束时做后置增强
<aop:after-throwing method="rollback" pointcut-ref="pc"/>
</aop:aspect>
</aop:config> -->
</beans>
测试类App
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class App {
@Autowired
private IUserService us;
@Test
public void testSave() throws Exception {
us.save();
}
@Test
public void testUpdate() throws Exception {
us.update();
}
}
十一.使用注解配置AOP
接口
public interface IUserService {
void save();
void update();
}
实现类
@Service
public class UserServiceImpl implements IUserService{
public void save() {
System.out.println("保存一个对象 ");
}
public void update() {
System.out.println(1/0);
System.out.println("更新 一个对象");
}
}
TransactionManager事务管理器
//事务管理器,作用各种数据库的事务
@Component
@Aspect
public class TransactionManager {
@Pointcut("execution(* cn.dusk._7_annotaion.service.*Service.*(..))")
public void pc() {}
public void begin() {
System.out.println("开始事务");
}
public void commit() {
System.out.println("提交事务");
}
public void rollback() {
System.out.println("回滚事务");
}
@Around("pc()")
public Object allInOne(ProceedingJoinPoint point) {
Object res = null;
try {
//开始事务
begin();
//业务方法
res = point.proceed();
System.err.println(1/0);
//提交事务
commit();
} catch (Throwable e) {
//回滚事务
rollback();
}
return res;
}
}
配置信息App-context.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">
<!-- 配置自动装配解析器 -->
<context:annotation-config/>
<!-- 组件扫描解析器 -->
<context:component-scan base-package="cn.dusk._7_annotaion"/>
<!-- 自动DI解析器 -->
<context:annotation-config/>
<!-- 自动代理 -->
<aop:aspectj-autoproxy/>
</beans>
测试类App
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class App {
@Autowired
private IUserService us;
@Test
public void testSave() throws Exception {
us.save();
}
}