博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring注解&Aop
阅读量:5354 次
发布时间:2019-06-15

本文共 7876 字,大约阅读时间需要 26 分钟。

有详细记录eclipse断网xml提示功能 细微区别如下图

在这里插入图片描述


使用需导入spring-aop-5.0.0.RELEASE.jar

创建User类

//作用一致 作为标识区分而已@Component("user")//@Service("user")//service层//@Controller("user")//web层//@Repository("user")//dao层//
//指定对象的作用范围@Scope(scopeName="singleton")//
public class User {
private String name; @Value("18")//通过反射Field赋值 破坏对象封装性 private Integer age; //@Autowired//自动装配 //如匹配多个相同类型的对象 将无法选择具体注入指定对象 //@Qualifier("car")//使用@Qualifier注解指定spring容器据对象名称装配 @Resource(name="car")//手动注入 据对象名称指定注入 一顶二 private Car car; public Car getCar() {
return car; } public void setCar(Car car) {
this.car = car; } public String getName() {
return name; } @Value("test")//通过Set方法赋值 推荐使用 public void setName(String name) {
this.name = name; } public Integer getAge() {
return age; } public void setAge(Integer age) {
this.age = age; } @PostConstruct//在对象被创建后调用init public void init(){
System.out.println("初始化方法"); } @PreDestroy//在销毁之前调用destory public void destory(){
System.out.println("销毁方法"); } //框架调用无参构造方法实例对象 构造方法没有重载时可默认不写jvm会补充}@component("car")class Car {
@value("玛莎拉蒂") private String name; @value("黑色") private String color;}

测试框架实例

public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = (User) applicationContext.getBean("user"); System.out.println(user); applicationContext.close(); }}

Console打印 com.java.entity.User@6591f517 测试成功

spring整合junit需导入spring-test-5.0.0.RELEASE.jar

//自动创建容器@RunWith(SpringJUnit4ClassRunner.class)//指定读取的配置文件位置@ContextConfiguration("classpath:applicationContext.xml")public class JUnitTest {
//将名为user的对象注入到变量user中 @Resource(name="user") private User user; @Test public void test() {
System.out.println(user); }}

spring aop

//spring 自动执行类型如下代码 为容器中管理的对象生成动态代理对象Proxy.newproxyinstance(classloader, Interface[] arr, Invocationhandeler handler);
spring混合使用两种代理模式 实现接口则会使用动态代理 否则使用cglib代理	动态代理 被代理对象必须要实现接口 才能产生代理对象	cglib代理 可对任何类生成代理 原理对目标对象进行继承代理

手动实现代理

public interface UserService {
void save(); void delete(); void update(); void find();}
public class UserServiceImpl implements UserService {
@Override public void save() {
System.out.println("保存用户"); } @Override public void delete() {
System.out.println("删除用户"); } @Override public void update() {
System.out.println("更新用户"); } @Override public void find() {
System.out.println("查找用户"); }}

动态代理实现

public class UserServiceProxyFactory implements InvocationHandler {
public UserServiceProxyFactory(UserService userService) {
this.userService = userService; } private UserService userService; public UserService getUserServiceProxy(){
//生成动态代理 UserService usProxy = (UserService) Proxy.newProxyInstance (UserServiceProxyFactory.class.getClassLoader(), UserServiceImpl.class.getInterfaces(), this); //返回对象 return usProxy; } @Override public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable {
System.out.println("打开事务"); Object invoke = method.invoke(userService, arg2); System.out.println("提交事务"); return invoke; }}

测试 动态代理

public static void main(String[] args) {
UserService us = new UserServiceImpl(); UserServiceProxyFactory factory = new UserServiceProxyFactory(us); UserService usProxy = factory.getUserServiceProxy(); usProxy.save();}

Console打印如下 说明测试成功

打开事务保存用户提交事务

cglib代理实现

public class UserServiceProxyFactory implements MethodInterceptor {
public UserService getUserServiceProxy() {
Enhancer en = new Enhancer();//生成代理对象 en.setSuperclass(UserServiceImpl.class);//设置进行代理对象 en.setCallback(this);//代理要做什么 UserService userService = (UserService) en.create();//创建代理对象 return userService; } @Override public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
System.out.println("打开事务");//打开事务 //调用原有方法 Object returnValue = methodProxy.invokeSuper(prxoyobj, arg); System.out.println("提交事务"); //提交事务 return returnValue; }}

测试 动态代理

public static void main(String[] args) {
UserServiceProxyFactory factory = new UserServiceProxyFactory(); UserService usProxy = factory.getUserServiceProxy(); usProxy.save(); //判断代理对象是否属于被代理对象类型 代理对象继承被代理对象 System.out.println(usProxy instanceof UserServiceImpl);//true}

Console打印如下 说明测试成功

打开事务保存用户提交事务

spring术语

Joinpoint(连接点):目标对象中 所有可以增强的方法Pointcut(切入点):目标对象中 已经増强的方法Advice(通知印/增强):增强的代码Target(目标对象):被代理对象Weaving(织入):将通知应用到切入点的过程Proxy(代理):将通知织入到目标对象之后 形成代理对象aspect(切面):切入点+通知

spring aop实现 xml

//spring aop包spring-aop-5.0.0.RELEASE.jarspring-aspects-5.0.0.RELEASE.jar//第三方aop包com.springsource.org.aopalliance-1.0.0.jarcom.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

准备目标对象

public class UserServiceImpl implements UserService {
@Override public void save() {
System.out.println("保存用户"); int i = 1/0; } @Override public void delete() {
System.out.println("删除用户"); } @Override public void update() {
System.out.println("更新用户"); } @Override public void find() {
System.out.println("查找用户"); }}

创建通知类

public class TestAdvice {
//前置通知 -> 目标方法运行之前调用 public void before() {
System.out.println("前置通知"); } //后置通知(出现异常不会调用) -> 目标方法运行之后调用 public void afterReturning() {
System.out.println("后置通知-出现异常不会调用"); } //环绕通知 -> 目标方法运行之前和之后都会调用 public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知-前"); Object proceed = joinPoint.proceed();//调用目标方法 System.out.println("环绕通知-后"); return proceed; } //异常拦截通知 -> 目标方法运行出现异常调用 public void afterThrowing() {
System.out.println("异常拦截通知"); } //后置通知(出现异常也会调用) -> 目标方法运行之后调用 public void afterException() {
System.out.println("后置通知-出现异常也会调用"); }}

把通知织入目标对象 导入spring-aop.xsd约束

在这里插入图片描述

测试

@RunWith(SpringJUnit4ClassRunner.class)//指定读取的配置文件位置@ContextConfiguration("classpath:com/test/applicationContext.xml")@Resource(name="userServiceImpl")public class JUnitTest {
private UserService userService; @Test public void test() {
userService.save(); }}

Console打印如下说明测试成功

出现异常时打印

前置通知环绕通知-前保存用户后置通知-出现异常也会调用异常拦截通知

不出现异常时打印

前置通知环绕通知-前保存用户后置通知-出现异常也会调用环绕通知-后后置通知-出现异常不会调用

spring aop实现 注解

创建通知类

@acpectpublic class TestAdvice {
@Pointcut("execution(* com.java.service.*ServiceImpl.*(..))") public void pointcut() {
} //前置通知 //指定该方法是前置通知 并制定切入点 @Before("TestAdvice.pointcut()") public void before(){
System.out.println("前置通知"); } //后置通知 @AfterReturning("execution(* com.java.service.*ServiceImpl.*(..))") public void afterReturning(){
System.out.println("后置通知-出现异常不会调用"); } //环绕通知 @Around("execution(* com.java.service.*ServiceImpl.*(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知-前"); Object proceed = pjp.proceed();//调用目标方法 System.out.println("环绕通知-后"); return proceed; } //异常通知 @AfterThrowing("execution(* com.java.service.*ServiceImpl.*(..))") public void afterException(){
System.out.println("异常拦截通知"); } //后置通知 @After("execution(* com.java.service.*ServiceImpl.*(..))") public void after(){
System.out.println("后置通知-出现异常也会调用"); }}

把通知织入目标对象

测试

@RunWith(SpringJUnit4ClassRunner.class)//指定读取的配置文件位置@ContextConfiguration("classpath:com/test/applicationContext.xml")@Resource(name="userServiceImpl")public class JUnitTest {
private UserService userService; @Test public void test() {
userService.save(); }}

Console打印如下说明测试成功

出现异常时打印

前置通知环绕通知-前保存用户后置通知-出现异常也会调用异常拦截通知

不出现异常时打印

前置通知环绕通知-前保存用户后置通知-出现异常也会调用环绕通知-后后置通知-出现异常不会调用

转载于:https://www.cnblogs.com/setlilei/p/10629441.html

你可能感兴趣的文章
Java 编程下实现随机无重复数字功能
查看>>
Android 编程下的代码混淆
查看>>
animation属性
查看>>
页内的模块和组件抽象规划经验
查看>>
安全-分析深圳电信的新型HTTP劫持方式
查看>>
将Centos的yum源更换为国内的阿里云源
查看>>
git diff 的用法
查看>>
HiPAC高性能规则匹配算法之查找过程
查看>>
layoutSubviews总结
查看>>
oracle在imp订单具体解释
查看>>
Java 中队列的使用
查看>>
博客新家来了!!!
查看>>
Python 列表推导实例
查看>>
[leetcode]28. Implement strStr()实现strStr()
查看>>
VMware虚拟机在局域网联网的设置方法
查看>>
python ConfigParser模块get方法简介
查看>>
几种开源的TCP/IP协议栈分析
查看>>
购书打折
查看>>
Google Protocol Buffer 的使用和原理[转]
查看>>
一步一境界
查看>>