IOC和AOP扩展
Posted pere
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IOC和AOP扩展相关的知识,希望对你有一定的参考价值。
L120201X1
构造注入,在L120108X1的项目上做出以下改变
1、改变UserServiceImpl.java成以下内容
package service.impl;
import dao.UserDao;
import entity.User;
import service.UserService;
//用户业务类,实现对User功能的业务管理
public class UserServiceImpl implements UserService {
//声明接口类型的引用,和具体实现类解耦合
private UserDao dao;
//dao 属性的setter访问器,会被Spring调用,实现设值注入
/*public void setDao(UserDao dao) {
this.dao=dao; }*/
public UserServiceImpl(UserDao dao) {
this.dao = dao;}
public UserServiceImpl() {}
public void addNewUser(User user) {
//调用用户DAO的方法保存用户信息
dao.save(user);}}
2、改变ApplicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="userDao" class="dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="service.impl.UserServiceImpl">
<constructor-arg>
<ref bean="userDao"/>
</constructor-arg></bean></beans>
3、运行AopTest.java得出以下结果:
保存用户信息到数据库
L120201X2
构造注入赋值顺序测试
1、在UserServiceImpl.java中增加以下内容
public UserServiceImpl(UserDao dao,String s1) {
this.dao = dao;
this.s1=s1;
}
public UserServiceImpl(String s2,UserDao dao) {
this.dao = dao;
this.s2=s2;
}
public void addNewUser(User user) {
dao.save(user);
System.out.println("s1="+s1);
System.out.println("s2="+s2);}}
2、ApplicationContext.xml增加以下内容
<bean id="userDao" class="dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="service.impl.UserServiceImpl">
<!-- 通过constructor-arg元素为构造方法里面的参数赋值 -->
<constructor-arg>
<ref bean="userDao"/>
</constructor-arg>
<constructor-arg>
<value>123</value>
</constructor-arg>
</bean>
3、运行AopTest.java得出以下结果:
保存用户信息到数据库
s1=null
s2=123
4、如果将
<constructor-arg>
<value>123</value>
</constructor-arg>
改成
<constructor-arg index="1">
<value>123</value>
</constructor-arg>
运行结果为:
保存用户信息到数据库
s1=123
s2=null
5、如果将上面的
<constructor-arg index="1">
<value>123</value>
</constructor-arg>
改成
<constructor-arg type="int">
<value>123</value>
</constructor-arg>
以及在UserServiceImpl.java中增加以下代码
private int i1;
public UserServiceImpl(UserDao dao,int i1) {
this.dao = dao;
this.i1=i1;
}
System.out.println("i1="+i1);
运行结果为
保存用户信息到数据库
s1=null
i1=123
L120202X1
1、将L120201X2中user的email变量改成age变量,同时增加其getter和setter方法
private String age;// 年龄
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
2、在UserDaoImpl的save方法中增加以下代码
System.out.println("已配置的用户信息如下:");
System.out.println(" 用户名为:"+user.getUsername());
System.out.println(" 年龄为:"+user.getAge());
System.out.println(" 邮箱为:"+user.getEmail());
3、UserServiceImpl中代码
package service.impl;
import dao.UserDao;
import entity.User;
import service.UserService;
public class UserServiceImpl implements UserService {
private UserDao dao;
public UserDao getDao() {
return dao;
}
public void setDao(UserDao dao) {
this.dao = dao;
}
public void addNewUser(User user) {
dao.save(user);
}
}
4、ApplicationContext.xml增加以下内容
头部增加xmlns:p="http://www.springframework.org/schema/p"
配置为
<bean id="user" class="entity.User" p:username="张三" p:age="20" p:email="test@123.com"></bean>
<bean id="userDao" class="dao.impl.UserDaoImpl" ></bean>
<bean id="userService" class="service.impl.UserServiceImpl" p:dao-ref="userDao">
</bean>
5、test类中代码
ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml");
UserService userService=(UserService)context.getBean("userService");
User user=(User)context.getBean("user");
userService.addNewUser(user);
5、运行结果
保存用户信息到数据库
已配置的用户信息如下:
用户名为:张三
年龄为:20
邮箱为:test@123.com
L120203X1
不同数据类型注入
1、user类代码
package entity;
/**
* 用户实体类
*/
public class User implements java.io.Serializable {
private String username; // 用户名
// getter & setter
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
2、TestEntity代码
package entity;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class TestEntity {
private String specialCharacter1; // 特殊字符值1
private String specialCharacter2; // 特殊字符值2
private User innerBean; // JavaBean类型
private List<String> list; // List类型
private String[] array; // 数组类型
private Set<String> set; // Set类型
private Map<String, String> map; // Map类型
private Properties props; // Properties类型
private String emptyValue; // 注入空字符串值
private String nullValue = "init value"; // 注入null值
public void setSpecialCharacter1(String specialCharacter1) {
this.specialCharacter1 = specialCharacter1;
}
public void setSpecialCharacter2(String specialCharacter2) {
this.specialCharacter2 = specialCharacter2;
}
public void setInnerBean(User user) {
this.innerBean = user;
}
public void setList(List<String> list) {
this.list = list;
}
public void setArray(String[] array) {
this.array = array;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProps(Properties props) {
this.props = props;
}
public void setEmptyValue(String emptyValue) {
this.emptyValue = emptyValue;
}
public void setNullValue(String nullValue) {
this.nullValue = nullValue;
}
public void showValue() {
System.out.println("特殊字符1:" + this.specialCharacter1);
System.out.println("特殊字符2:" + this.specialCharacter2);
System.out.println("内部Bean:" + this.innerBean.getUsername());
System.out.println("List属性:" + this.list);
System.out.println("数组属性[0]:" + this.array[0]);
System.out.println("Set属性:" + this.set);
System.out.println("Map属性:" + this.map);
System.out.println("Properties属性:" + this.props);
System.out.println("注入空字符串:[" + this.emptyValue + "]");
System.out.println("注入null值:" + this.nullValue);
}
}
3、test类代码
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import entity.TestEntity;
public class Test {
@org.junit.Test
public void test() {
// 使用ApplicationContext接口的实现类ClassPathXmlApplicationContext加载Spring配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
TestEntity entity = (TestEntity) ctx.getBean("testEntity");
entity.showValue();
}}
4、applicationContext.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-3.2.xsd">
<bean id="testEntity" class="entity.TestEntity">
<!-- 使用CDATA处理xml中特殊字符 -->
<property name="specialCharacter1">
<value><![CDATA[P&G]]></value>
</property>
<!-- 使用CDATA处理xml中特殊字符 -->
<property name="specialCharacter2">
<value>P&G</value>
</property>
<property name="innerBean">
<bean class="entity.User">
<property name="username">
<value>张三</value>
</property>
</bean>
</property>
<!-- 配置list集合类型的值 -->
<property name="list">
<list>
<value>足球</value>
<value>篮球</value>
</list>
</property>
<!-- 配置array的值 -->
<property name="array">
<list>
<value>足球</value>
<value>篮球</value>
</list>
</property>
<!-- 配置set集合类型的值 -->
<property name="set">
<list>
<value>足球</value>
<value>篮球</value>
</list>
</property>
<!-- 配置map集合类型的值 -->
<property name="map">
<map>
<entry>
<key><value>football</value></key>
<value>足球</value>
</entry>
<entry>
<key><value>basketball</value></key>
<value>篮球</value>
</entry>
</map>
</property>
<property name="props">
<props>
<prop key="football">足球</prop>
<prop key="basketball">篮球</prop>
</props>
</property>
<property name="emptyValue">
<value></value>
</property>
<property name="nullValue">
<null/>
</property>
</bean>
</beans>
5、运行结果
特殊字符1:P&G
特殊字符2:P&G
内部Bean:张三
List属性:[足球, 篮球]
数组属性[0]:足球
Set属性:[足球, 篮球]
Map属性:{football=足球, basketball=篮球}
Properties属性:{football=足球, basketball=篮球}
注入空字符串:[]
注入null值:null
L120204X1
异常抛出增强,在L120108X1的项目上做出以下改变
1、将UserSercviceLogger.java名字改为ErrorLogger.java
里面的方法为:
public void afterThrowing(JoinPoint jp,RuntimeException e){
log.error(jp.getSignature().getName()+"方法发成异常"+e);}
2、UserDaoImpl.java中的save方法改为
public void save(User user) {
System.out.println("保存用户信息到数据库");
throw new RuntimeException("为测试程序运行效果抛出的异常"); }
3、ApplicationContext.xml的配置为
<bean id="userDao" class="dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="service.impl.UserServiceImpl">
<property name="dao" ref="userDao"/>
</bean>
<!-- 声明增强类的bean元素 -->
<bean id="errorLogger" class="aop.ErrorLogger"></bean>
<!-- <aop:config>是最外层标签,所有的aop配置都需在里面进行 -->
<aop:config>
<!-- 切入点,id为名字可以随便取,但上下文一致,expression为表达式-->
<aop:pointcut id="pointcut" expression=
"execution(public void addNewUser(entity.User))"/>
<!--after-throwing方法定义为异常抛出增强,并引入切入点pointcut,通过throwing属性为参数e注入异常实例-->
<aop:aspect ref="errorLogger">
<!-- 设置后置增强,引入切入点,注入目标方法的返回值result-->
<aop:after-throwing method="afterThrowing"
pointcut-ref="pointcut" throwing="e"/>
</aop:aspect>
</aop:config>
3、运行结果为
保存用户信息到数据库‘
[ERROR] 2019-10-25 20:36:16,250 aop.ErrorLogger - addNewUser方法发成异常java.lang.RuntimeException: 为测试程序运行效果抛出的异常
L120204X2
最终增强,在L120204X1基础上修改代码
1、将ErrorLogger.java名字改为AfterLogger.java
里面的方法为
public void afterLogger(JoinPoint jp) {
log.info(jp.getSignature().getName() + " 方法结束执行。"); }
2、applicationContext.xml中的配置为
<bean id="dao" class="dao.impl.UserDaoImpl"></bean>
<bean id="service" class="service.impl.UserServiceImpl">
<property name="dao" ref="dao"></property>
</bean>
<!-- 声明增强方法所在的Bean -->
<bean id="theLogger" class="aop.AfterLogger"></bean>
<!-- 配置切面 -->
<aop:config>
<!-- 定义切入点 -->
<aop:pointcut id="pointcut" expression="execution(* service.UserService.*(..))" />
<!-- 引用包含增强方法的Bean -->
<aop:aspect ref="theLogger">
<!-- 将afterLogger()方法定义为最终增强并引用pointcut切入点 -->
<aop:after method="afterLogger" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
运行结果为
保存用户信息到数据库
10-25 21:20:18[INFO]aop.AfterLogger
-addNewUser 方法结束执行。
L120205X1
环绕增强,在L120204X2基础上修改代码
1、将AfterLogger.java名字改为AroundLogger.java
里面的方法为
public class AroundLogger {
private static final Logger log = Logger.getLogger(AroundLogger.class);
public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {
log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
+ " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
try {
Object result = jp.proceed();
log.info("调用 " + jp.getTarget() + " 的 "
+ jp.getSignature().getName() + " 方法。方法返回值:" + result);
return result;
} catch (Throwable e) {
log.error(jp.getSignature().getName() + " 方法发生异常:" + e);
throw e;
} finally {
log.info(jp.getSignature().getName() + " 方法结束执行。"); } }}
2、applicationContext.xml配置为
<bean id="dao" class="dao.impl.UserDaoImpl"></bean>
<bean id="service" class="service.impl.UserServiceImpl">
<property name="dao" ref="dao"></property>
</bean>
<!-- 声明增强方法所在的Bean -->
<bean id="theLogger" class="aop.AroundLogger"></bean>
<!-- 配置切面 -->
<aop:config>
<!-- 定义切入点 -->
<aop:pointcut id="pointcut" expression="execution(* service.UserService.*(..))" />
<!-- 引用包含增强方法的Bean -->
<aop:aspect ref="theLogger">
<!-- 将aroundLogger()方法定义为环绕增强并引用pointcut切入点 -->
<aop:around method="aroundLogger" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
3、运行结果为
-调用 service.impl.UserServiceImpl@7bb07f97 的 addNewUser 方法。方法入参:[entity.User@45f177b]
保存用户信息到数据库
10-25 21:41:05[INFO]aop.AroundLogger
-调用 service.impl.UserServiceImpl@7bb07f97 的 addNewUser 方法。方法返回值:null
10-25 21:41:05[INFO]aop.AroundLogger
-addNewUser 方法结束执行。
L120206X1
使用注解实现IOC配置
1、user代码
package entity;
public class User implements java.io.Serializable {
private Integer id; // 用户ID
private String username; // 用户名
private String password; // 密码
private String email; // 电子邮件
// getter & setter
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
2、UserDao代码
package dao;
import entity.User;
public interface UserDao {
public void save(User user);
}
3、UserDaoImpl.java代码
package dao.impl;
import org.springframework.stereotype.Repository;
import dao.UserDao;
import entity.User;
@Repository("userDao")
public class UserDaoImpl implements UserDao {
public void save(User user) {
// 这里并未实现完整的数据库操作,仅为说明问题
System.out.println("保存用户信息到数据库");
}
}
4、UserService.java代码
package service;
import entity.User;
public interface UserService {
public void addNewUser(User user);
}
5、UserServiceImpl.java代码
package service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import service.UserService;
import dao.UserDao;
import entity.User;
@Service("userService")
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
@Autowired
private UserDao dao;
public void setDao(UserDao dao) {
this.dao = dao;
}
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao.save(user);
}
}
6、Test.java代码
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserService;
import entity.User;
public class Test {
@org.junit.Test
public void test() {
// 使用ApplicationContext接口的实现类ClassPathXmlApplicationContext加载Spring配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 通过ApplicationContext接口的getBean()方法获取id或name为userService的Bean实例
UserService service = (UserService) ctx.getBean("userService");
User user = new User();
user.setId(1);
user.setUsername("test");
user.setPassword("123456");
user.setEmail("test@xxx.com");
service.addNewUser(user);
}
}
7、applicationContext.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="service,dao"></context:component-scan>
</beans>
8、运行结果
保存用户信息到数据库
L120206X2
在L120206X1基础上做以下修改
1、将UserDaoImpl.java复制粘贴一份,取名为UserDaoImpl2.java,里面代码为
package dao.impl;
import org.springframework.stereotype.Repository;
import dao.UserDao;
import entity.User;
@Repository("userDao2")
public class UserDaoImpl2 implements UserDao {
public void save(User user) {
// 这里并未实现完整的数据库操作,仅为说明问题
System.out.println("保存用户信息到数据库");}}
2、运行Test.java获得以下异常结果
type [dao.UserDao] is defined: expected single matching bean but found 2: userDao,userDao2
3、如何解决?将UserServiceImpl.java的代码修改成以下代码
package service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import service.UserService;
import dao.UserDao;
import entity.User;
@Service("userService")
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
@Autowired//按类型装配
@Qualifier("userDao")//指定装配的bean的名称
private UserDao dao;
public void setDao(UserDao dao) {
this.dao = dao;
}
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao.save(user);}}
4、运行结果
保存用户信息到数据库
5、如果将UserServiceImpl.java代码中的set方法注释掉进行测试
/*public void setDao(UserDao dao) {
this.dao = dao;
}*/
结果同样可以测试成功
6、将@Qualifier("userDao")放入set方法里面,UserServiceImpl.java代码为
package service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import service.UserService;
import dao.UserDao;
import entity.User;
@Service("userService")
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
private UserDao dao;
@Autowired//按类型装配
//指定装配的bean的名称
public void setDao(@Qualifier("userDao")UserDao dao) {
this.dao = dao;
}
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao.save(user);
}
}
测试结果同样成功
7、将example4复制粘贴一份取名为example4_2,用构造方法测试,UserServiceImpl.java中代码修改成以下代码后运行测试类
package service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import service.UserService;
import dao.UserDao;
import entity.User;
@Service("userService")
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
private UserDao dao;
@Autowired//按类型装配
public UserServiceImpl(@Qualifier("userDao")UserDao dao) {
this.dao = dao;
}
public UserServiceImpl() {
}
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao.save(user);}}
结果:保存用户信息到数据库
8、测试没有userDao的情况下的结果
将UserServiceImpl.java中的带参构造改成以下代码
@Autowired//按类型装配
public UserServiceImpl(@Qualifier("userDao3")UserDao dao) {
this.dao = dao;
}
测试结果报错
将UserServiceImpl.java中的带参构造改成以下代码
@Autowired(required=false)//按类型装配
public UserServiceImpl(@Qualifier("userDao3")UserDao dao) {
this.dao = dao;}
运行结果:
Console中没有结果
JUnit中的结果报:java.lang.NullPointerException
因为@Autowired(required=false),required值默认为true
9、复制粘贴example4改名为example5
删除UserDaoImpl2.java,删除UserServiceImpl.java中的@Autowired配置,进行@Resource配置,配置后的代码
package service.impl;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import service.UserService;
import dao.UserDao;
import entity.User;
@Service("userService")
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
@Resource(name="userDao")//通过@Resource注解进行装配
private UserDao dao;
//指定装配的bean的名称
public void setDao(UserDao dao) {
this.dao = dao;
}
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao.save(user);
}
}
运行结果:保存用户信息到数据库
再将上面的name属性删除掉,删除后的构造代码
@Service("userService")
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
@Resource//通过@Resource注解进行装配
private UserDao dao;
//指定装配的bean的名称
public void setDao(UserDao dao) {
this.dao = dao;
}
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao.save(user);
}
}
先根据属性名dao去找,找不到就根据userDao去找
运行结果:保存用户信息到数据库
10、复制粘贴UserDaoImpl.java改名为UserDaoImpl2.java,里面的代码改成为
package dao.impl;
import org.springframework.stereotype.Repository;
import dao.UserDao;
import entity.User;
@Repository("dao")
public class UserDaoImpl2 implements UserDao {
public void save(User user) {
// 这里并未实现完整的数据库操作,仅为说明问题
System.out.println("保存用户信息到数据库成功!!!");
}
}
运行结果:保存用户信息到数据库成功!!!
11、将@Resource放在set方法前
@Service("userService")
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
private UserDao dao;
//指定装配的bean的名称
@Resource(name="userDao")//通过@Resource注解进行装配
public void setDao(UserDao dao) {
this.dao = dao;
}
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao.save(user);
}
}
运行结果:保存用户信息到数据库
如果删除name属性则运行结果为:保存用户信息到数据库成功!!!
如果将setDao(UserDao dao)改成setUserDao(UserDao dao)
@Resource//通过@Resource注解进行装配
public void setUserDao(UserDao dao) {
this.dao = dao;
}
运行结果为:保存用户信息到数据库,说明是按照setUserDao而不是dao属性名
12、如果将UserServiceImpl.java代码改成
@Service("userService")
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
@Resource//通过@Resource注解进行装配
private UserDao dao1;
//指定装配的bean的名称
public void setUserDao(UserDao dao) {
this.dao1 = dao;
}
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao1.save(user);
}
}
运行结果为 expected single matching bean but found 2: userDao,dao
找到两个,原因是根据dao1去找找不到就根据类型去找,找到两个userDao类型的,删除UserDaoImpl2.java运行便不报错了
L120207X1
修改UserSercviceLogger.java和applicationContext.xml代码其他保存不变
一、测试前置增强
1、UserSercviceLogger.java代码
@Aspect
public class UserSercviceLogger {
private static Logger log=Logger.getLogger(UserSercviceLogger.class);
@Before("execution(* service.UserService.*(..))")
public void before(JoinPoint jp){
log.info("调用"+jp.getTarget()+"的"+jp.getSignature()
+"方法,方法参数"+Arrays.toString(jp.getArgs()));
}
public void afterReturning(JoinPoint jp,Object result){
log.info("调用"+jp.getTarget()+"的"+jp.getSignature()
+"方法,方法参数"+result); }}
2、applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<context:component-scan base-package="service,dao"></context:component-scan>
<bean class="aop.UserSercviceLogger"></bean>
<!-- 启动spring AOP的Aspect注解的支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
3、运行结果为
-调用service.impl.UserServiceImpl@2991c9a6的void service.UserService.addNewUser(User)方法,方法参数[entity.User@6bfbcd1b]
保存用户信息到数据库
二、测试后置增强
1、将UserSercviceLogger.java中后置增强代码改为
@AfterReturning(pointcut="execution(* service.UserService.*(..))",returning="result")
public void afterReturning(JoinPoint jp,Object result){
log.info("调用"+jp.getTarget()+"的"+jp.getSignature()
+"方法,方法参数"+result);
}
2、运行结果
-调用service.impl.UserServiceImpl@5e91af0f的void service.UserService.addNewUser(User)方法,方法参数[entity.User@2551050]
保存用户信息到数据库
10-27 15:17:40[INFO]aop.UserSercviceLogger
-调用service.impl.UserServiceImpl@5e91af0f的void service.UserService.addNewUser(User)方法,方法参数null
三、将切入点统一使用
1、将UserSercviceLogger.java改为
@Aspect
public class UserSercviceLogger {
private static Logger log=Logger.getLogger(UserSercviceLogger.class);
@Pointcut("execution(* service.UserService.*(..))")
public void pointcut(){}
@Before("pointcut()")
public void before(JoinPoint jp){
log.info("调用"+jp.getTarget()+"的"+jp.getSignature()
+"方法,方法参数"+Arrays.toString(jp.getArgs()));
}
@AfterReturning(pointcut="pointcut()",returning="result")
public void afterReturning(JoinPoint jp,Object result){
log.info("调用"+jp.getTarget()+"的"+jp.getSignature()
+"方法,方法参数"+result);
}
}
2、测试运行结果
与二中的结果一样
四、测试异常抛出增强
1、复制粘贴example6名字改为example7
将L120204X1exampleAfterThrowing中的ErrorLogger.java复制粘贴在example7中,删除UserSercviceLogger.java
2、ErrorLogger.java中代码为
@Aspect
public class ErrorLogger {
private static Logger log=Logger.getLogger(ErrorLogger.class);
@AfterThrowing(pointcut="execution(* service.UserService.*(..))",throwing="e")
public void afterThrowing(JoinPoint jp,RuntimeException e){
log.error(jp.getSignature().getName()+"方法发成异常"+e);
}
}
3、UserDaoImpl.java中代码
@Repository("userDao")
public class UserDaoImpl implements UserDao {
public void save(User user) {
System.out.println("保存用户信息到数据库");
throw new RuntimeException("为测试程序运行效果抛出的异常");
}
}
3、applicationContext.xml中bean元素改为
<bean class="aop.ErrorLogger"></bean>
4、运行结果为
保存用户信息到数据库
10-27 15:49:58[ERROR]aop.ErrorLogger
-addNewUser方法发成异常java.lang.RuntimeException: 为测试程序运行效果抛出的异常
五、最终增强
1、复制粘贴example7,命名为example8,将使用Schema定义最终增强中的AfterLogger.java复制粘贴在example8中,删除ErrorLogger.java
2、AfterLogger.java中代码为
@Aspect
public class AfterLogger {
private static final Logger log = Logger.getLogger(AfterLogger.class);
@After("execution(* service.UserService.*(..))")
public void afterLogger(JoinPoint jp) {
log.info(jp.getSignature().getName() + " 方法结束执行。");
}
}
3、applicationContext.xml中bean元素改为
<bean class="aop.AfterLogger"></bean>
4、在有异常抛出的情况下运行结果
保存用户信息到数据库
10-27 16:59:02[INFO]aop.AfterLogger
-addNewUser 方法结束执行。
六、环绕增强
2、复制粘贴example8,命名为example9,将使用Schema定义环绕增强中的AroundLogger.java复制粘贴在example9中,删除AfterLogger.java
2、AroundLogger.java中代码为
@Aspect
public class AroundLogger {
private static final Logger log = Logger.getLogger(AroundLogger.class);
@Around("execution(* service.UserService.*(..))")
public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {
log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
+ " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
try {
Object result = jp.proceed();
log.info("调用 " + jp.getTarget() + " 的 "
+ jp.getSignature().getName() + " 方法。方法返回值:" + result);
return result;
} catch (Throwable e) {
log.error(jp.getSignature().getName() + " 方法发生异常:" + e);
throw e;
} finally {
log.info(jp.getSignature().getName() + " 方法结束执行。");
}
}
}
3、applicationContext.xml中bean元素改为
<bean class="aop.AroundLogger"></bean>
4、在有异常抛出的情况下运行结果
-调用 service.impl.UserServiceImpl@68dda0a 的 addNewUser 方法。方法入参:[entity.User@291c9a1e]
保存用户信息到数据库
10-27 17:08:07[ERROR]aop.AroundLogger
-addNewUser 方法发生异常:java.lang.RuntimeException: 为测试程序运行效果抛出的异常
10-27 17:08:07[INFO]aop.AroundLogger
-addNewUser 方法结束执行。
以上是关于IOC和AOP扩展的主要内容,如果未能解决你的问题,请参考以下文章