Spring的学习

一、Spring概述

(一)spring是什么

spring是一个高度灵活的轻量级框架,其目的是降低企业级应用开发的复杂度。
spring在当前的j2ee项目中应用非常广泛,采用java 语言开发。

Spring是免费开源的,地址:

https://spring.io/projects/spring-framework

(二)spring功能介绍

Spring 容器提供了IOC机制,可以创建对象以及管理对象之间的调用关系,避免了硬编码造成的程序耦合。
提供了AOP(面向切面编程方式)功能,可以实现很多特定功能。
声明式事务控制处理。
对jdbc进行了轻量级的封装,可以更加灵活的去操作数据库。
提供了MVC设计模式的解决方案
提供了文件上传、定时器等常用工具类。
对于其他优秀框架的支持(如:Struts、Hibernate、MyBatis、Quartz等)
(三)spring功能模块划分
在这里插入图片描述

二、JAVA类的耦合与解耦

(一)什么是程序的耦合
在开发中,可能会写很多的类,而有些类之间不可避免的产生依赖关系,这种依赖关系称之为耦合。
有些依赖关系是必须的,有些依赖关系可以通过优化代码来解除的。

代码示例

public class CustomerServiceImpl implements CustomerService 

以上的代码表示:业务层调用持久层,并且此时业务层在依赖持久层的接口和实现类。如果此时没有持久层实现类,编译将不能通过。这种依赖关系就是我们可以通过优化代码解决的。
还有如下面的代码:
我们的类依赖了MySQL的具体驱动类,如果这时候因为某些原因数据库的品牌从MySQL改为Oracle,那么需要通过改源码来修改数据库驱动。这显然不是我们想要的。

public class JdbcDemo01{
	public static void main(String[] args) throws Exception {
		Class.forName("com.mysql.jdbc.Driver");
	}}

(二)解决耦合的思路
当是我们学习JDBC时,是通过反射来注册驱动的,代码如下:

Class.forName("com.mysql.jdbc.Driver");

这时的好处是,我们的类中不再依赖具体的驱动类,此时就算删除mysql的驱动jar包,依然可以编译。但是因为没有驱动类,所以不能运行。
不过,此处也有个问题,就是我们反射类对象的全限定类名字符串是在java类中写死的,一旦要改还是要修改源码。
解决这个问题也很简单,使用配置文件配置。

1.2.1 工厂模式解耦

在实际开发中我们可以把所有的dao和service和action对象使用配置文件配置起来,当启动服务器应用加载的时候,通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。

2.2.2 控制反转-Inversion Of Control

上面解耦的思路有2个问题:
1、存哪去?
分析:由于我们是很多对象,肯定要找个集合来存。这时候有Map和List供选择。
到底选Map还是List就看我们有没有查找需求。有查找需求,选Map。
所以我们的答案就是
在应用加载时,创建一个Map,用于存放action,Service和dao对象。
我们把这个map称之为容器。
2、还是没解释什么是工厂?
工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。
原来:
我们在获取对象时,都是采用new的方式。是主动的。
在这里插入图片描述

现在:
我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。
在这里插入图片描述

这种被动接收的方式获取对象的思想就是控制反转,它是spring框架的核心之一。
它的作用只有一个:削减计算机程序的耦合。

三、工厂设计模式

什么是工厂设计模式?
工厂设计模式,顾名思义,就是用来生产对象的,在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则,如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦
定义:一个工厂方法,依据传入的参数,生成对应的产品对象;
角色:
1、抽象产品
2、具体产品
3、具体工厂
4、产品使用者
使用说明:先将产品类抽象出来,比如,苹果和梨都属于水果,抽象出来一个水果类Fruit,苹果和梨就是具体的产品类,然后创建一个水果工厂,分别用来创建苹果和梨;代码如下:
水果接口

public interface Fruit {
    void whatIm();
}

具体类 苹果

public class Apple implements Fruit {
    @Override
    public void whatIm() {
        //苹果
    }
}

具体类 梨

public class Pear implements Fruit {
    @Override
    public void whatIm() {
        //梨
    }
}

具体工厂 水果工厂
public class FruitFactory {

    public Fruit createFruit(String type) {

        if (type.equals("apple")) {//生产苹果
            return new Apple();
        } else if (type.equals("pear")) {//生产梨
            return new Pear();
        }

        return null;
    }
}

产品使用

 FruitFactory mFactory = new FruitFactory();
 Apple apple = (Apple) mFactory.createFruit("apple");//获得苹果
 Pear pear = (Pear) mFactory.createFruit("pear");//获得梨

package com.tjetc.domain;

public interface Fruit {
    void  whatIm();
}

package com.tjetc.domain;

public class Apple implements Fruit {
    @Override
    public void whatIm() {
        System.out.println("我是苹果");
    }
}

package com.tjetc.domain;

public class Pear implements Fruit {
    @Override
    public void whatIm() {
        System.out.println("我是梨");
    }
}

package com.tjetc.domain;

public class FruitFactory {
    public Fruit createFruit(String type){
        if (type.equals("apple")){
            return new Apple();
        }
        else if (type.equals("pear")){
            return new Pear();
        }
        return null;
    }
}

  public static void main(String[] args) {
//        创建水果工厂
        FruitFactory fruitFactory = new FruitFactory();
//        通过工厂生产水果
        Fruit apple = fruitFactory.createFruit("apple");
        Fruit pear = fruitFactory.createFruit("pear");
        apple.whatIm();
        pear.whatIm();
    }

四、IoC概述及作用

(一)什么是IoC
Inversion of Control:控制权的转移,创建对象的权利由应用程序转移到容器称为控制反转
(二)IoC的作用
削减计算机程序的耦合(解除我们代码中的依赖关系)

五、Spring基于XML的IoC配置入门

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

<bean id="userService" class="com.tjetc.service.UserService"></bean>

package com.tjetc.service;

public class UserService {
public UserService() {
System.out.println(“UserService()”);
}

public void add(){
    System.out.println("UserService.add()");
}

}

package com.tjetc;

import com.tjetc.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext.xml”);
UserService userService = context.getBean(UserService.class);
userService.add();
}
}

UserService()
UserService.add()

六、Spring基于XML的IoC配置

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

<!-- 告诉spring容器创建一个userDao对象-->
    <bean id="userDao" class="com.tjetc.dao.UserDao"></bean>
    <!--   告诉spring容器创建一个userService对象-->
    <bean id="userService" class="com.tjetc.service.UserService">
<!--        使用属性的setter方法注入setUserDao-->
        <property name="userDao" ref="userDao"></property>
    </bean>

 
package com.tjetc.service;

public class UserService {
    public UserService() {
        System.out.println("UserService()");
    }

    public void add(){
        System.out.println("UserService.add()");
    }
}

public class UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public UserService() {
        System.out.println("UserService()");
    }

    public void add(){
        System.out.println("UserService.add()");
        userDao.add();
    }
}



package com.tjetc.dao;

public class UserDao {
   public void add(){
       System.out.println("userDao.add()");
    }
}

public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserService userService = context.getBean(UserService.class);
    userService.add();
}

UserService()
UserService.add()
userDao.add()

七、构造方法注入

public UserService(UserDao userDao) {
    System.out.println("UserService.UserService");
    this.userDao = userDao;
}

<!--  bean:让spring容器创建对象  id:代表bean(就是new好的java对象)的名字  class:代表你要spring容器创建的类的全限定名-->
   <bean id="userService" class="com.tjetc.service.UserService">
       <constructor-arg name="userDao" ref="userDao"></constructor-arg>
   </bean>
<!--    配置userDao的bean节点-->
    <bean id="userDao" class="com.tjetc.dao.UserDao"></bean>

八、Spring基于Annotation的IoC配置

Annotation:注解

<!--配置组件的扫描com.tjetc本包及其子孙包下的所有的在类上标注有@Controller,@Service,@Repository,@Component注解的类,
spring会把标注了这些注解的类当做你配置bean节点一样纳入spring容器管理-->

<context:component-scan base-package="com.tjetc"></context:component-scan>

package com.tjetc.service;

import com.tjetc.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public UserService() {
        System.out.println("UserService()");
    }

    public void add(){
        System.out.println("UserService.add()");
        userDao.add();
    }
}

package com.tjetc.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserDao {
   public void add(){
       System.out.println("userDao.add()");
    }
}

public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserService userService = context.getBean(UserService.class);
    userService.add();
}

UserService()
UserService.add()
userDao.add()

【总结】
1.什么是IOC?
Inversion of Control 控制反转 创建对象的权利由应用程序转移到了容器称之为控制反转
2.Ioc作用
削减耦合,减少依赖

3.基于XML的Ioc配置

1.pom.xml: spring-context
2.applicationContext.xml <bean id="bean的名字" class="类的全限定名">
3.测试:
	ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
	UserSerVice userService=(UserSerVice)context.getBean("userService");
	userService.add();
4.属性的setter方法
	UserSerVice:
		private UserDao userDao;
		setter
    applicationContext.xml:
		<property name="userDao" ref="userDao">
5.构造方法
    applicationContext.xml:
		<constructor-arg name="userDao" ref="userDao">
	UserSerVice:
		private UserDao userDao;
		构造方法

4.基于注解的Ioc

   1.applicationContext.xml:
       <context:component-scan base-package="com.tjetc"></context:component-scan>
	2.类配置组件的扫描com.tjetc本包及其子孙包下的所有的在类上标注有@Controller,@Service,@Repository,@Component注解的类,
spring会把标注了这些注解的类当做你配置bean节点一样纳入spring容器管理

5.代理的本质:在不改变目标类方法的代码的情况下对目标类的方法进行增强
6.静态代理
由程序员创建代理类在程序运行前代理类的.class文件就已经存在了.
静态代理需要以下角色
1.接口
目标类和代理类都要实现该接口
2.目标类
被代理的类
3.代理类
代理目标类的类
4.测试类
创建目标对象
创建代理对象(注入目标对象)
调用代理类的方法
7.动态代理:在程序运行时运用反射机制动态创建而成,不是提前写好的,是后期动态生成的
1.JDK动态代理
1、 新建一个接口
2、 为接口创建一个实现类(就是被代理的类)
3、 创建中间类实现java.lang.reflect.InvocationHandler接口 重写invoke方法(Object proxy,Method method,Object[] args) Object invoke=method.invoke(obj,args);
4、 测试 UserSerVice userService=(UserSerVice)Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),new JdkHandler(obj));
2.CGLIB
1.pom.xml cglib
2.创建目标类
3.写方法拦截器: MethodInterceptor intercept(Object proxy,Method method,Object[] args,MethodProxy methodProxy){
Object result=methodProxy.invokeSuper(proxy,args);
}
4.测试类
1.创建目标类对象
2.Enhancer enhancer=new Enhancer();
enhancer.setSuperClass(UserSerVice.class);
enhancer.setCallback(new MyInterceptor(obj));
UserSerVice proxy=(UserSerVice)enhancer.create();
proxy.add();
8.aop

1.aop
2.join point 连接点
3.point cut 切点
4.aspect 切面=切点+增强
5.advice 增强

9.xml aop

1.切面类
2.配置

		<!--配置目标类-->
		<bean id="userService" class="com.tjetc.service.UserService"></bean>
	<!--    配置切面类-->
		<bean id="myAspect" class="com.tjetc.aspect.MyAspect"></bean>
	<!--    aop配置切面-->
		<aop:config>
	<!--                  配置切面-->
			<aop:aspect id="myaop" ref="myAspect">
	<!--                        配置切点   expression定位到连接点(目标类的方法)的条件表达式-->
				<aop:pointcut id="mycut" expression="execution(* com.tjetc.service..*.*(..))"/>
	<!--            配置增强-->
	<!--            <aop:before method="doBefore" pointcut-ref="mycut"></aop:before>-->
	<!--            <aop:after-returning method="doAfterReturning" pointcut-ref="mycut"></aop:after-returning>-->
	<!--            <aop:after method="doAfter" pointcut-ref="mycut"></aop:after>-->
	<!--            <aop:after-throwing method="doAfterThrowing" pointcut-ref="mycut"></aop:after-throwing>-->
				<aop:around method="doAround" pointcut-ref="mycut"></aop:around>
			</aop:aspect>
		</aop:config>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值