文章目录
一、什么是注入?
注入:通过Spring的配置文件,为成员变量赋值。
Set注入:Spring调用Set方法 通过配置文件 为成员变量赋值。
构造注入:Spring调用构造方法 通过配置文件 为成员变量赋值。
二、五种增强方式
1. 概念
Aop的五种增强处理如下:
名称 | 作用 |
---|---|
前置增强(Before Advice) | 在目标方法执行之前执行。 |
后置增强(After returning advice) | 在目标方法执行后执行,无论目标方法运行期间是否出现异常。 |
环绕增强(Around Advice) | 在一个方法执行之前,执行通知 |
异常增强(After Throwing Advice) | 在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知 |
最终增强(After finally) | 在目标方法执行之后,只有在方法成功完成时,才能执行通知。 |
【当目标方法出错时,后置增强不执行,最终增强会执行;有异常执行异常增强,不报错执行后置增强】
2. 五种增强方式的代码步骤
第一步:导包
//pom.xml
<!--切面要用的包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
<!--logj-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
第二步:创建目标方法
//dao、service接口
public interface UserDao {
public int addNewUser(User user);
}
//dao实现
public class UserDaoImpl implements UserDao {
public int addNewUser(User user) {
System.out.println("新添加一个对象~~~");
return 0;
}
}
//service实现
@Setter
public class UserServiceImpl implements UserService {
private UserDao userDao;
public int addNewUser(User user) {
return userDao.addNewUser(user);
}
}
第三步:创建增强类【根据自己建立的包单独创建一个aop包,我的目录“com.jules.aop.UserLogge”,在配置文件是要创建bean的】
/**
* 增强类
*/
public class UserLogger {
private static final Logger log = Logger.getLogger(UserServiceLogger.class);
//前置增强
public void beforeLogger(JoinPoint jp) {
System.out.print("我是前置增强…………");
System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().
getName() + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
}
//后置增强
public void afterReturning(JoinPoint jp, Object result) {
System.out.print("我是后置增强…………");
log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().
getName() + " 方法。方法返回值:" + result);
}
//最终增强
public void afterLogger(JoinPoint jp) {
System.out.print("我是最终增强…………");
log.info("最终增强:"+jp.getSignature().getName()+"方法结束执行。");
}
//异常增强
public void afterThrowing(JoinPoint jp,RuntimeException e){
log.error("异常抛出:"+jp.getSignature().getName()+"方法发生异常:"+e);
}
//环绕增强,需要调用目标方法
public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable{
System.out.println("环绕增强开始…………");
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()+"方法结束执行。");
System.out.println("环绕增强结束~~~");
}
}
}
第四步:配置文件
//添加关于aop的头部文件:
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
<!--实例化增强类-->
<bean id="serviceLogger" class="com.jules.aop.UserLogger"/>
<!--配置切面-->
<aop:config>
<!--定义切入点 id自定义 -->
<aop:pointcut id="pointcut" expression="execution(* com.jules.service.*.*.*(..))"></aop:pointcut>
<!--做增强处理-->
<aop:aspect ref="serviceLogger">
<!--做前置增强 织入-->
<aop:before method="beforeLogger" pointcut-ref="pointcut"/>
<!--后置增强-->
<aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
<!--最终增强-->
<aop:after method="afterLogger" pointcut-ref="pointcut"/>
<!--异常增强-->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>
<!--环绕增强-->
<aop:around method="aroundLogger" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
第五步:测试类
public class Test {
@Test
public void addNewUser() {
//使用ClassPathXmlApplicationContext读取配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("配置文件名");
//使用getBean("bean中ID属性值")获取对象
UserService userService = (UserService) context.getBean("userService");
userService.addNewUser(new User()); //添加空对象测试异常增强
}
}
3.spring AOP配置元素
目录 | 说明 |
---|---|
aop:config | Aop配置 |
aop:pointcut | 定义切点 |
aop:aspect | 定义切面 |
aop:before | 定义前置增强 |
aop:after-returning | 定义后置增强 |
aop:after | 定义最终增强 |
aop:after-throwing | 定义异常增强 |
aop:around | 定义环绕增强 |
aop:aspectj-autoproxy/ | 启动@AspectJ注解驱动的切面 |
4.execution表达式匹配规则
<aop:pointcut id="pointcut" expression="execution(* com.jules.service.*.*.*(..))"></aop:pointcut>
public * addNewUser(entity.User)----- “ * ”表示匹配所有类型的返回值。
public void *(entity.User)------“ * ”表示匹配所有方法名。
public void addNewUser(..)-------“..”表示匹配所有参数个数和类型。
* com.service.*.*(..)-------匹配com.service包下所有类的所有方法。
* com.service..*.*(..)-------匹配com.service包及其子包下所有类的所有方法
三、P命名空间注入
在Spring框架中,p命名空间注入是一种简化XML配置的方式,它允许我们使用更简洁的语法来进行属性注入。这种方式可以减少配置的冗余代码,使配置文件更加清晰易读。
<bean id="唯一标识" class="类的全路径"
p:"属性1"="注入的值" p:"属性2"="注入的值" />
<bean id="唯一标识" class="类的全路径"
p:属性-ref="注入的Bean" />
注:配置文件中使用p命名空间时,需要先添加p命名空间的声明 xmlns:p=“http://www.springframework.org/schema/p”
四.不同数据类型注入
一.使用list
package com.cskt.DayTwo;
import lombok.Data;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@Data
public class JavaListContext{
List manList; //注入 集合 有序 允许重复 有下标
}
<bean id="JavaCollection" class="com.cskt.DayTwo.JavaCollection">
<property name="manList">
<list>
<value>List01</value>
<value>List02</value>
</list>
</property>
</bean>
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
JavaCollection collection = (JavaCollection) context.getBean("JavaCollection");
collection.getManList().stream().forEach(item->{
System.out.println(item);
});
二.使用Map
<property name="集合属性名">
<map><!-- 普通值用<value>标签,对象用<bean>标签 -->
<entry key="键1" value="值1"></entry>
<entry key="键2" value="值2"></entry>
</map>
</property>
三.使用set
<property name="集合属性名" value="字符串"></property>
四.使用Props
<property name="集合属性名">
<props>
<prop key="键1">值1</prop>
<prop key="键2">值2</prop>
</props>
</property>