spring框架的IOC和AOP总结

spring框架的重点

1.IOC/DI:控制反转/依赖注入

2.AOP:面向切面编程

IoC(控制反转)/DI(依赖注入)

(1)IoC:指原先有程序员主动new实例化对象的事情,转交给Spring负责

(2)控制反转中的控制:指控制类的对象

(3)控制反转中的反转:指交给Spring控制(spring的xml文件配置bean工厂)

(4)IoC最大的作用:解耦,程序员不需要管理对象,解除了管理对象与程序员之间的耦合。
(5)当一个类(A)需要依赖另一个类(B)对象时,将类B赋值给类A的过程就叫做依赖注入。
简单来说依赖注入为:
依赖:一个对象需要使用另一个对象
注入:通过setter方法进行另一个对象实例设置

依赖注入的三种方式

1、构造方法依赖注入
把2中的set方法变成构造函数就ok了。
2、setter方法注入

public class BookServiceImpl implements BookService {

    private BookDao bookDao;
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
    @Override
    public void addBook() {
        this.bookDao.addBook();
    }
}

3、接口注入
好像是用的不多,暂时不做了解。

代码块

BookDao接口

public interface BookDao {
    public void addBook();
    }

BookDao接口实现类

public class BookDaoImpl implements BookDao {
    @Override
    public void addBook() {
        System.out.println(" di  add book");
    }
}

BookService接口

public interface BookService {
    public abstract void addBook();
}

BookService接口实现类

public class BookServiceImpl implements BookService {

    private BookDao bookDao;
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
    @Override
    public void addBook() {
        this.bookDao.addBook();
    }
}

bean对应的applicationContext.xml的配置

<bean id="bookServiceId" class="com.my.service.BookServiceImpl">
        <property name="bookDao" ref="bookDaoId"></property>
    </bean>

    <!-- 创建dao实例 -->
    <bean id="bookDaoId" class="com.my.dao.BookDaoImpl"></bean>

测试类:

public class BookServiceImplTest {
 @Test
    public void demo01(){
        //从spring容器获得
        String xmlPath = "applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        BookService bookService = (BookService) applicationContext.getBean("bookServiceId");
        bookService.addBook();//di  add book
    }
}

控制台输出

 di  add book

AOP编程

一 AOP的基本概念

(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知

(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用

(3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around

(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式

(5)AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类
4.通知执行的优先级

进入目标方法时,先织入Around,再织入Before,退出目标方法时,先织入Around,再织入AfterReturning,最后才织入After。

注意:Spring AOP的环绕通知会影响到AfterThrowing通知的运行,不要同时使用!同时使用也没啥意义。

5.切入点的定义和表达式

切入点表达式的定义算是整个AOP中的核心,有一套自己的规范

Spring AOP支持的切入点指示符:

(1)execution:用来匹配执行方法的连接点

A:@Pointcut("execution(* com.aijava.springcode.service..*.*(..))")

第一个表示匹配任意的方法返回值,…(两个点)表示零个或多个,上面的第一个…表示service包及其子包,第二个表示所有类,第三个*表示所有方法,第二个…表示方法的任意参数个数

B:@Pointcut("within(com.aijava.springcode.service.*)")

within限定匹配方法的连接点,上面的就是表示匹配service包下的任意连接点

C:@Pointcut("this(com.aijava.springcode.service.UserService)")

this用来限定AOP代理必须是指定类型的实例,如上,指定了一个特定的实例,就是UserService

D:@Pointcut("bean(userService)")

bean也是非常常用的,bean可以指定IOC容器中的bean的名称

后言: spring 的环绕通知和前置通知,后置通知有着很大的区别,主要有两个重要的区别:

1) 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知 是不能决定的,他们只是在方法的调用前后执行通知而已,即目标方法肯定是要执行的。

2) 环绕通知可以控制返回对象,即你可以返回一个与目标对象完全不同的返回值,虽然这很危险,但是你却可以办到。而后置方法是无法办到的,因为他是在目标方法返回值后调用
aop的xml形式的配置

<aop:config>
        <aop:aspect id="loggerAspect" ref="logger">
            <aop:around method="record" pointcut="(execution(* com.aijava.distributed.ssh.service..*.add*(..))
                                              or   execution(* com.aijava.distributed.ssh.service..*.update*(..))
                                              or   execution(* com.aijava.distributed.ssh.service..*.delete*(..)))
                                            and !bean(logService)"/>
        </aop:aspect>
</aop:config>

代码块

point类 切入点函数

public class point {
    public int add(int a,int b){
        System.out.println("切入点");
        return a+b;
    }
}

IOC的入口(java代码配置bean,等同于xml方式)

//IOC的入口
@Configuration
@EnableAspectJAutoProxy
public class config {
    @Bean
    public  point point(){
        return  new point();
    }
    @Bean
    public point1 point1(){
        return  new point1();
    }
}

切面类

@Aspect
public class point1 {
        @Pointcut("execution(public int com.ok.point.*(..))")
        public  void kk(){}
        @Before("kk()")
        public void k(){
            System.out.println("@before执行");
        }
    @Around("kk()")
    public  Object testAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("@around函数前");
      Object A=joinPoint.proceed();
        System.out.println("@around函数后");return A;
    }
}

测试类

public class pointcut1Test {
        @Test
        public void test01(){
            AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(config.class);
            point c = app.getBean(point.class);
            int result = c.add(4, 7);
            System.out.println("结果是:"+result);
            app.close();
        }
}

控制台输出

@around函数前
@before执行
切入点
@around函数后
结果是:11
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值