Spring

spring简介
spring是一个轻量级的java开源的框架,使用java语言编写。其核心技术是:IOC,AOP。spring的作用是解决java对象之间的耦合,解决模块模块之间的耦合。spring又叫做:容器, spring作为容器, 装的是java对象。 可以让spring创建java对象, 给属性赋值。

spring容器
在这里插入图片描述

Spring优点
Spring 是一个框架,是一个半成品的软件。有 20 个模块组成。它是一个容器管理对象,容器是装东西的,Spring 容器不装文本,数字。装的是对象。Spring 是存储对象的容器。
(1) 轻量
Spring 框架使用的 jar 都比较小,一般在 1M 以下或者几百 kb。Spring核心功能的所需的 jar 总共在 3M 左右。
Spring 框架运行占用的资源少,运行效率高。不依赖其他 jar
(2) 针对接口编程,解耦合
Spring 提供了 Ioc 控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成。对象之间的依赖解耦合。
(3) AOP 编程的支持
通过 Spring 提供的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付在 Spring 中,开发人员可以从繁杂的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
(4) 方便集成各种优秀框架
Spring 不排斥各种优秀的开源框架,相反 Spring 可以降低各种框架的使用难度,Spring 提供了对各种优秀框架(如 Struts,Hibernate、MyBatis)等的直接支持。简化框架的使用。Spring 像插线板一样,其他框架是插头,可以容易的组合到一起。需要使用哪个框架,就把这个插头放入插线板。不需要可以轻易的移除。

IOC的理解

IoC,Inversion of Control:控制反转。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

DI:Dependency Injection.依赖注入。开发者只需要提供要使用的对象名称就可以了。对象如何创建,如何查找,都是由Spring容器内部实现。

核心代码


	    //自主控制bean
        SomeService someService1 = new SomeServiceImpl();
        someService1.doSome();
        
       //把bean交给spring管理
        //获取配置bean文件,spring容器在加载bean配置文件时就已经创建好了其中的所有bean,等到后续程序要
        //用的时候就会直接用,创建好的bean是会放在内存里面。
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("userBean.xml");
       //拿到bean,强制转换,父类的引用指向子类的对象
        Student studentInfo = (Student) applicationContext.getBean("studentInfo");
        //获取注入的bean的实体类信息
        System.out.println("姓名:"+studentInfo.getName()+"年龄:"+studentInfo.getAge()+"学校:"+studentInfo.getSchool().getName());


    <!--在xml设置bean属性需要实体类中实现set方法-->
    <bean name="studentInfo" class="com.study.component.Student">
        <property name="name" value="张三"></property>
        <property name="age" value="18"></property>
        <!--配置对象属性-->
        <property name="school" ref="mySchool"/>
    </bean>

    <bean name="mySchool" class="com.study.component.School">
        <property name="name" value="县三中"></property>
        <property name="address" value="西渡"></property>
    </bean>

常用注解及介绍

@component:定义java对象,需要在配置文件(<context:component-scan base-package=“注解所在的包名”/>)中指定需要扫描的包,不然不会生效
@Respository:dao层,持久层对象,表示独享能访问数据库。
@Service :service对象,业务层对象,处理业务逻辑,具有事物能力。
@Controller : 控制器对象, 接收请求,显示请求的处理结果。 视图层对象

@Autowired与@Resouce
@Autowired(required = false)
@Qualifier(“mySchool”)//指定bean name注入@Resouce(“beanName”)(需要指定beanName)与Autowired这两个注解结合的一致。

用来给引用类型赋值的注解,直接放在引用类型上面。
@Autowired(required = false)默认required = true表示这个这个在注入的时候找不到bean导致引用类型失败,程序会报错。而改为false之后注入失败程序不会报错,但注入的引用类型的值就会为空。
注意:@Resouce是java 自带的包,且1.8版本之后的java已不支持此注解。@Autowired是Spring内部的jar包,导入相关依赖就可以使用。

AOP的理解
Aspect Orient Programming(面向切面编程)

aspect:切面,可以在不影响应用程序的情况下,对当前程序增加业务功能,使程序可复用性变强。一般用在:日志功能,事务功能,权限验证。

AOP中的术语

1)Aspect:切面, 给业务方法增加的功能。
2)JoinPoint:连接点, 连接切面的业务方法。 在这个业务方法执行时,会同时执行切面的功能。
3)Pointcut: 切入点, 是一个或多个连接点集合。 表示这些方法执行时,都能增加切面的功能。
表示切面执行的位置。
4)target: 目标对象, 给那个对象增加切面的功能, 这个对象就是目标对象。
5)Advice:通知(增强),表示切面的执行时间。 在目标方法之前执行切面,还是目标方法之后执行切面。

AOP中重要的三个要素

Aspect, Pointcut , Advice. 这个概念的理解是: 在Advice的时间,在Pointcut的位置, 执行Aspect

代码表示
采用的jar包,manven如下:

  <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
        <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
          <version>5.3.0</version>
        </dependency>
        <!--日志文件管理包——logStart-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!--AOP 包 start-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.8</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.11.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.11.2</version>
        </dependency>
        <!--AOP end-->
        <dependency> <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>

aopBean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <bean name="loginService" class="com.study.aop.service.impl.LoginServiceImpl"></bean>
    <bean name="registerService" class="com.study.aop.service.impl.RegisterServiceImpl"></bean>

    <!-- 声明切面类-->
    <bean name="myAspect" class="com.study.aop.handle.MyAspect"></bean>

    <context:component-scan base-package="com.study.aop.service.impl"></context:component-scan>
    <!--声明自动代理-->
    <aop:aspectj-autoproxy/>
</beans>

MyAspect 切面类

需要注意的是这个表达式(execution后面需要接修饰符、 参数返回值、 然后就是指定类名(可用代替)、参数可有可无、异常(此例没有体现))
execution(public void com.study.aop.service.impl.
.user*(String,String))

/**
 * @author lx
 *
 * 创建切面类
 */
@Aspect
public class MyAspect {

    //切面方法必须是public、 void、 无参(有参必须是JoinPoint类型)的
    //执行的execution必须是基本数据类型+String
//    @Before(value = "execution(public void com.study.aop.service.impl.LoginServiceImpl.userLogin*(String,String))")
//    public void myBefore(){
//        System.out.println("这个是前置通知******执行了前置业务"+new Date());
//    }
    //可以带参,必须时候JoinPoint
    @Before(value = "execution(public void com.study.aop.service.impl.*.user*(String,String))")
    public void myBefore(JoinPoint joinPoint){
        System.out.println("连接点的方法定义:"+joinPoint.getSignature());
        System.out.println("连接点方法的参数个数:"+joinPoint.getArgs().length);
        System.out.println("这个是前置通知******执行了前置业务"+new Date());

    }
    //在目标方法执行之后执行。
    @AfterReturning(value = "execution(public void com.study.aop.service.impl.*.user*(String,String))")
    public void myAfter(JoinPoint joinPoint){
        System.out.println("连接点的方法定义:"+joinPoint.getSignature());
        System.out.println("连接点方法的参数个数:"+joinPoint.getArgs().length);
        System.out.println("这个是后置通知******执行了后置业务"+new Date());
    }
}

loginService及其实现类(还有个注册及其实现类,实现方法都一样就没添加了)

/**
 * @author lx
 */
public interface LoginService {
    /**
     *
     * @return
     * 用户登录
     * 用户登录信息
     */
    void userLogin(String name,String passWord);
}

/**
 * @author lx
 * 登录实现类
 */
public class LoginServiceImpl implements LoginService {


    @Override
    public void userLogin(String name,String password) {
        System.out.println("======================");
        System.out.println("执行用户登录业务"+"用户名:"+name+",密码:"+password);
        System.out.println("======================");
    }
    public void userLoginOf() {

        System.out.println("执行用户登录之后的业务");

    }
}

测试类

/**
 * @author lx
 */
public class ApplicationRun {
    public static void main(String[] args) {
        String beansPath  ="aopBean.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(beansPath);
        LoginService loginService = (LoginService)applicationContext.getBean("loginService");
        RegisterService registerService = (RegisterService)applicationContext.getBean("registerService");
        registerService.userRegister("zhansan","123456");
        loginService.userLogin("zhansan","123456");
         //LoginService loginService = new LoginProxyImpl();
        //loginService.userLogin("zhansan","123456");
    }

}

环绕通知Around

在执行业务方法之前和之后增加功能,可以用来记录日志或者处理事务,比前置通知跟后置通知更加灵活。
优点:
可以在执行方法的前后都增加功能。
可以控制方法是否执行。
可以修改目标方法的返回值。

//@Around()
    //环绕通知可以有返回值,可以包含ProceedingJoinPoint类型的一个参数
    @Around("execution(* *com.study.aop.service.impl.*.do*(String))")
    public Object doSome(ProceedingJoinPoint joinPoint) throws Throwable {
        Object object = null;
        System.out.println("执行了环绕通知,在目标方法之前执行,可以输出日志");
        //proceed()方法会调用目标方法
        Object proceed = joinPoint.proceed();
        System.out.println("执行了环绕通知,在执行方法之后执行,可以处理事物");
        //如果需要修改目标方法的返回值,需要return 你想return的结果。不想修改的话可以直接返回proceed
        return "myAspect 的 Around";
    }
   

测试类

 public static void main(String[] args) {
     ApplicationContext applicationContext = new ClassPathXmlApplicationContext("aopBean.xml");
     DoServiceByAround doService = (DoServiceByAround) applicationContext.getBean("doService");
     //这个返回结果实际是myaspect 下面环绕通知方法Around的返回结果,不是dosome方法的
     String str = doService.doSome("hello");

     System.out.println("调用之后的返回结果"+str+"=======");
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值