Spring框架的IOC和AOP的简单项目实现

一、Spring框架介绍

Spring框架是为了解决企业应用开发复杂性而创建的,是Java应用钟最广的框架,它的成功来源于设计思想,而不是技术本身,即IOC(inversion of control,控制反转)AOP(Aspect oriented programming,面向切面编程) 的核心概念。它将面向接口的编程思想贯穿整个系统,解决了项目中各层的松耦合问题,简化企业项目的开发。

1、IOC(控制反转)

Spring IOC像是一个容器,认为Java资源都是Java Bean,IOC的目标是管理好Bean。在 Spring IOC里管理了各种 Bean(资源),它们的创建、事件、行为、资源之间的依赖关系等,都由 Spring IOC 容器根据配置文件的描述来完成管理任务。因此,使用 Spring 框架就是将对象的创建、销毁、初始化等一系列生命周期的过程,都交给 Spring 容器来处理。

如果没有IOC?
平常我们写代码,如果一个类ServiceA要调用另一个类ServiceB的某个方法,就需要在类ServiceA的方法里new一个类ServiceB的对象。

假如现在你有几十个类都需要用到ServiceB的某个方法,那你就需要在几十个类里,都分别去new一个ServiceB的对象。

有一天,业务改了,你写了一个新的类ServiceC,类ServiceB就废弃不用了。那之前调用ServiceB的几十个类,你就得把几十个类中
“ServiceB b= new ServiceB ()”的代码改成“ServiceC c= new ServiceC ()”

如果你漏掉了一处,那项目跑的时候又去调用对象ServiceB 的方法,但此时ServiceB 的逻辑已经废弃了…

IOC解决了什么问题?
创建一个接口ServiceB,然后给它创建一个实现类ServiceBImpl。在ServiceA里注入接口ServiceB。

这个时候,当你的项目启动的时候,Spring 容器在底层使用java的反射技术,去扫描项目中的Bean。它首先发现类 ServiceA 里引用了接口ServiceB,然后它去找现在是谁实现了接口ServiceB,它发现原来是类ServiceBImpl实现了接口ServiceB,此时根据这层依赖关系,它就会在类 ServiceA实例化一个ServiceBImpl的对象。依赖注入,就是Spring容器用反射技术,根据注解或配置文件去创建Bean, 然后根据Bean之间的依赖和引入关系,去实例化对应的对象,实现了类和类之间彻底的解耦。

2、AOP(面向切面的编程)

AOP解决了什么问题?
解决重复代码问题。AOP,就是通过动态代理技术生成类的一个动态代理类,这个动态代理类实现了你的类的所有方法,然后根据你的注解,给每个方法织入一些增强代码。从而避免了项目中大量重复代码,一改就得改几十个方法的问题了。

二、简单项目(完整代码)

蛋糕店项目:可以进行制作多种口味(柠檬和芝士)蛋糕操作,输入需要制作的蛋糕口味后,使用AOP模拟实现了在制作开始前检查烤箱是否适合烘培、烘培结束后打包蛋糕、送出蛋糕的功能,制作完成后会输出到控制台。

Cake.java
package cn.java.bean;
public class Cake {
    String type ="";
    public  void addMilk(){

    }
    public  void addFlour(){

    }
    public String getName(){

        return type;
    }
}
CheeseCake.java
package cn.java.bean;
public class CheeseCake extends Cake{
    @Override
    public void addMilk() {
        System.out.println("给蛋糕加牛奶!");
    }

    @Override
    public void addFlour() {
        System.out.println("给蛋糕加面粉!");
    }

    @Override
    public String getName() {
        return "芝士蛋糕";
    }
}
LemonCake.java
package cn.java.bean;
public class LemonCake extends Cake{
    @Override
    public void addMilk() {
        System.out.println("给蛋糕加牛奶!");
    }

    @Override
    public void addFlour() {
        System.out.println("给蛋糕加面粉!");
    }

    @Override
    public String getName() {
        return "柠檬蛋糕";
    }
}
CakeDao.java
package cn.java.dao;
import cn.java.bean.Cake;
public interface CakeDao {
    public int addCake(Cake cake);
}
CakeDaoImpl.java
package cn.java.dao.impl;
import cn.java.bean.Cake;
import cn.java.dao.CakeDao;
public class CakeDaoImpl implements CakeDao {
    @Override
    public int addCake(Cake cake) {
        System.out.println("cake" +"对象信息为:"+cake);
        System.out.println("已将cake订单存入账本");
        return 1;
    }
}
CakeMakeService.java
package cn.java.service;
import org.springframework.stereotype.Service;
@Service
public interface CakeMakeService {
    public void CakeMake(String type);
    public void CakeMakeAndPack(String type);
}
CakeMakeServiceImpl.java
package cn.java.service.impl;

import cn.java.bean.Cake;
import cn.java.dao.CakeDao;
import cn.java.service.CakeMakeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

import java.applet.AppletContext;
import java.util.HashMap;
@Service
public class CakeMakeServiceImpl implements CakeMakeService {

    @Override
    public void CakeMake(String type) {
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        Cake cake = (Cake) context.getBean(type);
        cake.addMilk();
        cake.addFlour();
        String result = cake.getName();
        System.out.println("叮叮叮叮~  "+result+"新鲜出炉!");


    }

    @Override
    public void CakeMakeAndPack(String type) {

        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        Cake cake = (Cake) context.getBean(type);
        CakeDao cakeDaoImpl = (CakeDao) context.getBean("CakeDaoImpl");
        cake.addMilk();
        cake.addFlour();
        String result = cake.getName();
        System.out.println("叮叮叮叮~  "+result+"新鲜出炉!");
        cakeDaoImpl.addCake(cake);
    }
}

CheckBefore.java
package cn.java.aop;

import org.aspectj.lang.annotation.Aspect;
@Aspect
public class CheckBefore {
    public void checkSafe(){
        System.out.println("[AOP前置通知]: 正在检查当前烤箱是否可以开始烘培......");
    }

    public void checkSuc(){
        System.out.println("[AOP前置通知]: 当前机器正常!开始烘培....");
    }

}
DeliveryAfter.java
package cn.java.aop;

import org.aspectj.lang.annotation.Aspect;

@Aspect
public class DeliveryAfter {
    public void deliveryExit(){
        System.out.println("[AOP结束通知]: 已安全送出蛋糕.....");
    }
}
PackAfter.java
package cn.java.aop;

import org.aspectj.lang.annotation.Aspect;
@Aspect
public class PackAfter {
    public void pack() {
        System.out.println("[AOP返回通知]: 正在打包蛋糕....");
    }
}
aop.xml
<!-- 配置目标类,运算bean -->
    <bean id="cakeServiceImpl" class="cn.java.service.impl.CakeMakeServiceImpl" >
    </bean>

    <!--    AOP实验-->
    <!-- 配置切面类,检查bean ,第一个切面-->
    <bean id="CheckBefore" class="cn.java.aop.CheckBefore"></bean>
    <!-- 配置切面类,打包bean ,第二个切面-->
    <bean id="PackAfter" class="cn.java.aop.PackAfter"></bean>
    <!-- 配置切面类,送出bean ,第三个切面-->
    <bean id="DeliveryAfter" class="cn.java.aop.DeliveryAfter"></bean>

    <!--    <aop:config></aop:config>-->

    <!--2. 配置aop,开始将目标方法和各切面中的通知方法,进行织入-->
    <aop:config>
        <!--  配置连接点(切入点)-->
        <aop:pointcut expression="execution (* cn.java.service.impl.CakeMakeServiceImpl.* (..))" id="cakePoint"/>

        <!-- 配置各切面,不要哪个切面时,注释掉即可 -->

        <!--  配置检测检查环境切面 1. CheckBefore,aop:before:表示前置通知
         -->
        <aop:aspect ref="CheckBefore" >
            <aop:before method="checkSafe" pointcut-ref="cakePoint"/>
            <aop:before method="checkSuc" pointcut-ref="cakePoint"/>

        </aop:aspect>

        <!-- 配置打包切面 2:PackAfter,aop:after:表示后置通知
            order="2":表示执行的顺序,数字越大越先执行
         -->
        <aop:aspect ref="PackAfter" order="2">
            <aop:after method="pack" pointcut-ref="cakePoint"/>
        </aop:aspect>

        <!--  配置送出切面 3:DeliveryAfter,aop:after:后置通知
        order="1":表示执行的顺序,数字越大越先执行
        -->
        <aop:aspect ref="DeliveryAfter" order="1">
            <aop:after method="deliveryExit" pointcut-ref="cakePoint"/>
        </aop:aspect>
    </aop:config>
application.xml
 	<bean id="Cake" class="cn.java.bean.Cake">
    </bean>

    <bean id="Lemon" class="cn.java.bean.LemonCake" parent="Cake">
    </bean>

    <bean id="Cheese" class="cn.java.bean.CheeseCake" parent="Cake">
    </bean>


    <bean id="CakeDaoImpl" class="cn.java.dao.impl.CakeDaoImpl">
    </bean>

    <!--   引入局部配置文件  -->
    <import resource="aop.xml"/>
log4j.properties
# log4JÈÕÖ¾¿ò¼ÜµÄÅäÖÃÎļþ ÎļþÃû×Ö²»ÄܸÄ
# DEBUG ±íʾÈÕÖ¾µÄ¼¶±ð  µ÷ÊÔ
# Console ÈÕÖ¾´òÓ¡ÔÚ¿ØÖÆ̨
log4j.rootLogger=INFO, Console 
log4j.appender.Console=org.apache.log4j.ConsoleAppender  
log4j.appender.Console.layout=org.apache.log4j.PatternLayout  
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n  

# ÄÄЩÈÕÖ¾ÐèÒª´òÓ¡
log4j.logger.java.sql.ResultSet=INFO  
log4j.logger.org.apache=INFO  
log4j.logger.java.sql.Connection=DEBUG  
log4j.logger.java.sql.Statement=DEBUG  
log4j.logger.java.sql.PreparedStatement=DEBUG 
test1.java
import cn.java.dao.CakeDao;
import cn.java.service.CakeMakeService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test1 {
    @Test
    public void testCalServiceImpl(){
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

        CakeMakeService cakeMakeServiceImp = (CakeMakeService) context.getBean("cakeServiceImpl");

        System.out.println("------------------------CakeMake方法测试------------------------");
        cakeMakeServiceImp.CakeMake("Lemon");
        System.out.println("------------------------------------------------");
        cakeMakeServiceImp.CakeMake("Cheese");
        System.out.println("------------------------------------------------");


        System.out.println("------------------------CakeMakeAndPack方法测试------------------------");
        cakeMakeServiceImp.CakeMakeAndPack("Lemon");
        System.out.println("------------------------------------------------");
        cakeMakeServiceImp.CakeMakeAndPack("Cheese");
        System.out.println("------------------------------------------------");
    }
}

三、运行结果

test1运行结果
请添加图片描述
请添加图片描述

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值