Spring Ioc与Aop注解方式配置
程序员文章站
2022-07-12 13:30:15
...
引入需要的spring.jar:
项目结构:
@Repository、@Service 和 @Controller。
在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。
主要代码:
1、CustomerServiceImpl实现类:三种注入方式
package service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import dao.CustomerDao;
import entity.Customer;
import service.CustomerService;
@Service("service")
public class CustomerServiceImpl implements CustomerService {
//方法一
@Autowired
@Qualifier("dao")
private CustomerDao dao;
//方法二
// @Autowired
// public void setDao(@Qualifier("dao") CustomerDao dao) {
// this.dao = dao;
// }
public void addNewUser(Customer user) {
// TODO Auto-generated method stub
dao.save(user);
}
// public CustomerServiceImpl() {
// // TODO Auto-generated constructor stub
// }
//方法三
// @Autowired
// public CustomerServiceImpl(@Qualifier("dao") CustomerDao dao) {
// // TODO Auto-generated constructor stub
// this.dao=dao;
// }
}
2、CustomerDaoImpl实现类:
package dao.impl;
import org.springframework.stereotype.Repository;
import dao.CustomerDao;
import entity.Customer;
@Repository("dao")
public class CustomerDaoImpl implements CustomerDao{
@Override
public void save(Customer user) {
// 这里并未实现完整的数据库操作,仅为说明问题
System.out.println("保存用户信息到数据库");
//System.out.println(user.getUsername()+"---"+user.getPassword()+"---"+user.getEmail());
}
}
3、配置文件applicationContext:
<?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:p="http://www.springframework.org/schema/p"
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/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- 定义dao对象,并指定id为dao -->
<!-- <bean id="dao" class="dao.impl.UserDaoImpl"></bean> -->
<!-- 定义service对象,并指定id为service -->
<!-- 为UserService的属性赋值,值得注意的是,这里要调用setDao()方法 -->
<!-- <bean id="service" class="service.impl.UserServiceImpl">
<property name="dao" ref="dao"></property>
</bean> -->
<!-- 使用p命名空间的方式进行dao属性的注入,依赖setter方法 -->
<!-- <bean id="service" class="service.impl.UserServiceImpl" p:dao-ref="dao"></bean> -->
<!-- 扫描包中注解标注的类 -->
<context:component-scan base-package="service,dao"></context:component-scan>
<!-- 声明增强方法所在的Bean -->
<bean id="theLogger" class="aop.CustomerServiceLogger"></bean>
<!-- 配置切面 -->
<aop:config>
<aop:pointcut id="pointcut"
expression="execution(public void addNewUser(entity.Customer))" />
<!-- 引用包含增强方法的Bean -->
<aop:aspect ref="theLogger">
<!-- 将before()方法定义为前置增强并引用pointcut切入点 -->
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
<!-- 将afterReturning()方法定义为后置增强并引用pointcut切入点 -->
<!-- 通过returning属性指定为名为result的参数注入返回值 -->
<aop:after-returning method="afterReturning"
pointcut-ref="pointcut" returning="result" />
<!-- 将afterThrowing()方法定义为异常抛出增强并引用pointcut切入点 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>
<!-- 将afterLogger()方法定义为最终增强并引用pointcut切入点 -->
<aop:after method="afterLogger" pointcut-ref="pointcut"/>
<!-- 将aroundLogger()定义为环绕增强并引用pointcut切入点 -->
<aop:around method="aroundLogger" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
<!-- 开启基于@AspectJ切面的注解处理器 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
4、Aop增强方法类CustomerServiceLogger:
package aop;
import java.util.Arrays;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component("theLogger")
public class CustomerServiceLogger {
private static final Logger log = Logger.getLogger(CustomerServiceLogger.class);
@Pointcut("execution(public void addNewUser(entity.Customer))")
public void serviceAspect(){}
//代表前置增强的方法
@Before("serviceAspect()")
public void before(JoinPoint jp) {
log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
+ " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
}
//代表后置增强的方法
@AfterReturning(pointcut="serviceAspect()",returning="result")
public void afterReturning(JoinPoint jp, Object result) {
log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
+ " 方法。方法返回值:" + result);
}
//异常抛出增强的方法
@AfterThrowing(pointcut = "serviceAspect()",throwing = "e")
public void afterThrowing(JoinPoint jp,RuntimeException e) {
log.error(jp.getSignature().getName()+"方法发生的异常"+e);
}
//最终增强
@After("serviceAspect()")
public void afterLogger(JoinPoint jp) {
log.info(jp.getSignature().getName()+"方法结束执行");
}
//环绕增强
/*@Around("serviceAspect()")*/
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) {
// TODO: handle exception
log.error(jp.getSignature().getName()+"方法发生的异常"+e);
throw e;
}
finally{
log.info(jp.getSignature().getName()+"方法结束执行");
}
}
}
5、log4j.properties:
# rootLoggeræ¯æææ¥å¿çæ ¹æ¥å¿,ä¿®æ¹è¯¥æ¥å¿å±æ§å°å¯¹æææ¥å¿èµ·ä½ç¨
# ä¸é¢çå±æ§éç½®ä¸,æææ¥å¿çè¾åºçº§å«æ¯info,è¾åºæºæ¯con
log4j.rootLogger=info,con
# å®ä¹è¾åºæºçè¾åºä½ç½®æ¯æ§å¶å°
log4j.appender.con=org.apache.log4j.ConsoleAppender
# å®ä¹è¾åºæ¥å¿çå¸å±éç¨çç±»
log4j.appender.con.layout=org.apache.log4j.PatternLayout
# å®ä¹æ¥å¿è¾åºå¸å±
log4j.appender.con.layout.ConversionPattern=%d{MM-dd HH:mm:ss}[%p]%c%n -%m%n