aspectj依赖的jar包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
1、接口
public interface CityService {
void query();
}
2、接口实现
@Component
public class CityServiceImpl implements CityService {
public void query(){
System.out.println("spring -----init -----");
}
}
一、简单的Spring AOP实例
3、切面
@Component
@Aspect
public class AopAspect {
@Pointcut("execution(* com.boss.spring.aop..*.*(..))")
public void pointCut(){
System.out.println("oap pointCut-----------");
}
@Before("pointCut()")
public void before(){
System.out.println("oap before -----------");
}
@After("execution(* com.boss.spring.aop..*.*(..))")
public void after(){
System.out.println("oap after -----------");
}
}
4、配置类
@Configuration
@ComponentScan("com.boss.spring.aop")
@EnableAspectJAutoProxy
public class Appconfig {
}
5、测试类
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
//Spring容器就是一个ConcurrentHashMap
//代理对象不是在getBean的事后代理的,代理是在init初始化的时候完成了
ac.getBean(CityService.class).query();
}
}
6、运行结果
oap before -----------
spring -----init -----
oap after -----------
二、自定义后置处理器
BeanPostProcessor:可以看出,该接口定义了两个方法,分别在bean实例化之后放到我们的容器之前和之后去执行,方法的返回值为一个object,这个object呢就是我们存在于容器的对象了(所以这个位置我们是不是可以对我们的bean做一个动态的修改,替换等等操作,所以这也是我们spring的扩展点之一,后面结合我么自己手写aop来详细讲解这个扩展点的应用)
实例:接口和实现类与上面一致
3、定义动态代理
public class CityHandler implements InvocationHandler {
private Object object;
public CityHandler(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("CityHandler -------------------");
return method.invoke(object,args);
}
}
4、自定义AOP后置处理器
@Component
public class CityPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("cityServiceImpl"))
bean = Proxy.newProxyInstance
(CityPostProcessor.class.getClassLoader(),new Class[]{CityService.class},new CityHandler(bean));
return bean;
}
}
5、配置类
@Configuration
@ComponentScan("com.boss.spring.aop")
//@EnableAspectJAutoProxy
public class Appconfig {
}
6、测试类
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
//Spring容器就是一个ConcurrentHashMap
//代理对象不是在getBean的事后代理的,代理是在init初始化的时候完成了
ac.getBean(CityService.class).query();
}
}
7、运行结果
CityHandler -------------------
spring -----init -----
如果想使用标签进行AOP控制,可以自定义标签
第4步将@Component注释掉,变为:
//@Component
public class CityPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("cityServiceImpl"))
bean = Proxy.newProxyInstance
(CityPostProcessor.class.getClassLoader(),new Class[]{CityService.class},new CityHandler(bean));
return bean;
}
}
然后自定义标签:
@Import(CityPostProcessor.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableCity {
}
5、第5步配置类注入自定义标签,变为:
@Configuration
@ComponentScan("com.boss.spring.aop")
@EnableCity
public class Appconfig {
}
再次运行即可