Spring框架(一)

Spring框架总览

spring-overview.png

官方文档摘要(5.1.7RELEASE)

beans和context包是IoC的基础

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory.

这些bean定义对应于组成应用程序的实际对象。通常,您定义服务层对象、数据访问对象(DAOs)、表示对象(如Struts)操作实例、Hibernate SessionFactories等基础设施对象、JMS队列等等。通常,不会在容器中配置细粒度域对象,因为通常由dao和业务逻辑负责创建和加载域对象。不过,您可以使用Spring与AspectJ的集成来配置在IoC容器之外创建的对象

These bean definitions correspond to the actual objects that make up your application. Typically,

you define service layer objects, data access objects (DAOs), presentation objects such as Struts
Action instances, infrastructure objects such as Hibernate SessionFactories, JMS Queues, and so
forth. Typically, one does not configure fine-grained domain objects in the container, because it is
usually the responsibility of DAOs and business logic to create and load domain objects. However,
you can use Spring’s integration with AspectJ to configure objects that have been created outside
the control of an IoC container.

IoC底层实现原理

以持久层调用数据库为例Dao层用传统JDBC实现

/**
*用户管理Dao接口
*/
public interface UserDao {
    public void save();
}
/**
*用户管理Dao接口实现类
*/
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.printl("UserDaoImpl执行了...");
    }
}
/**
*业务层调用Dao
*/
public class UserServiceImpl{
    public void saveUser(){
        UserDao userDao = new UserDaoImpl();
    }
}

上述UserDaoImpl与UserDao之间存在耦合关系,如果UserDao的实现类需要用Hibernate进行数据调用则需要创建新的类USerDaoHibernateImpl,同时 UserDao userDao = new USerDaoHibernateImpl();如果又不想用hibernate,改用mybatis,则又需要改底层实现,很麻烦。

解决方案一:静态工厂

在XxxDao和XxxDaoImpl之间建立工厂,XxxDao需要什么就从工厂中拿,工厂中提供Dao实现.但现在工厂和UserDaoImpl之间有了耦合

class BeanFactory{
    public static UserDao getUserDao(){
        return new UserDaoImpl();
    }
    public static CustomDao getCustomDao(){
        return new CustomDaoImpl();
    }
}

解决方案二:静态工厂+配置文件xml+反射(这个即为IoC底层实现原理)

<bean id="userDao" class="com.xxx.xxx.UserDaoImpl">
<bean id="userDao1" class="com.xxx.xxx.UserDaoHibernateImpl">       
class BeanFactory{
    public static Object getBean(String id){
        //解析XML
        //反射
        Class clazz = Class.forName("com.xxx.xxx.UserDaoImpl");
        return clazz.newInstance();
    }
}

AOP底层实现原理

代理机制:

Spring 的 AOP 的底层用到两种代理机制:

  • JDK 的动态代理 :针对实现了接口的类产生代理。==底层默认使用此方法==
  • Cglib 的动态代理 :(类似于Javassist第三方代理技术)针对没有实现接口的类产生代理. 应用的是底层的字节码增强的技术 生成当前类的子类对象.
package com.yuan.web3;

public interface GoodsDao {
    public void find();
    public String add() ;
    public void delete() ;
    public void update() ;
}
package com.yuan.web3;

public class GoodsDaoImpl implements GoodsDao{
    public void find() {
        System.out.println("查询商品");
    }
    public String add() {
        System.out.println("增加商品");
        return "iphone8--";
    }
    public void delete() {
        System.out.println("删除商品");
        int t =1/0;
    }
    public void update() {
        System.out.println("更新商品");
    }
}

编写代理类

JDK动态代理方式

package com.yuan.web3;

import java.lang.reflect.Method;
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;

public class MyJDKProxy implements InvocationHandler {
    private GoodsDao goodsDao;
    public MyJDKProxy(GoodsDao goodsDao) {
        this.goodsDao = goodsDao;
}
// 编写工具方法:生成代理:
    public GoodsDao createProxy(){
        GoodsDao  goodsDaoProxy  =  (GoodsDao)
        Proxy.newProxyInstance(goodsDao.getClass().getClassLoader(),
                goodsDao.getClass().getInterfaces(), this);
        return goodsDaoProxy;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        if("delete".equals(method.getName())){
            System.out.println("权限校验================");
        }
        return method.invoke(goodsDao, args);
    }

}

cglib动态代理方式

public class MyCglibProxy implements MethodInterceptor{
    private GoodsDao goodsDao;
    public MyCglibProxy(GoodsDao goodsDao){
        this.goodsDao = goodsDao;
    }
    
    // 生成代理的方法:
    public GoodsDao createProxy(){
        // 创建 Cglib 的核心类:
        Enhancer enhancer = new Enhancer();
        // 设置父类:
        enhancer.setSuperclass(GoodsDao.class);
        // 设置回调:
        enhancer.setCallback(this);
        // 生成代理:
        GoodsDao goodsDaoProxy = (GoodsDao) enhancer.create();
        return goodsProxy;
    }
    
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
    methodProxy) throws Throwable {
        if("delete".equals(method.getName())){
            Object obj = methodProxy.invokeSuper(proxy, args);
            System.out.println("日志记录================");
            return obj;
        }
        return methodProxy.invokeSuper(proxy, args);
    }
}

编写测试类

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.yuan.web3.GoodsDao;
import com.yuan.web3.GoodsDaoImpl;
import com.yuan.web3.MyJDKProxy;

public class AopTest {
    
    @Test
    /**
    *JDK动态代理方式
    */
    public void aopTest2() {
        GoodsDao goodsDao = new GoodsDaoImpl();
        GoodsDao proxy = new MyJDKProxy(goodsDao).createProxy();
        proxy.find();
        proxy.add();
        proxy.update();
        proxy.delete(); 
    }
    
    @Test
    /**
     * Cglib动态代理方式
     */
    public void aopTest3() {
        GoodsDao goodsDao = new GoodsDaoImpl();
        GoodsDao proxy = new MyCglibProxy(goodsDao).createProxy();
        //proxy.find();
        proxy.add();
        proxy.update();
        proxy.delete();

}

一,基本概念

1. IoC(Inversion of Control)

IOC:控制反转,将对象的创建权反转给了Spring。

==IoC is also known as dependency injection (DI)==. It is a process whereby objects define
their dependencies (that is, the other objects they work with) only through constructor arguments,
arguments to a factory method, or properties that are set on the object instance after it is
constructed or returned from a factory method. The container then injects those dependencies
when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of
Control) of the bean itself controlling the instantiation or location of its dependencies by using
direct construction of classes or a mechanism such as the Service Locator pattern.

IoC依赖以下两个包,包中包含两个重要的类BeanFactory和ApplicationContext

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container

The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory. It adds:

  • Easier integration with Spring’s AOP features
  • Message resource handling (for use in internationalization)
  • Event publication
  • Application-layer specific contexts such as the WebApplicationContext for use in web applications

2. DI( Dependency Injection)

DI: 依赖注入,前提必须有IOC的环境,Spring管理这个类的时候将类的依赖的属性注入(设置)进来。

Dependency injection (DI) is a process whereby objects define their dependencies (that is, the other
objects with which they work) only through constructor arguments, arguments to a factory method,
or properties that are set on the object instance after it is constructed or returned from a factory
method. The container then injects those dependencies when it creates the bean. This process is
fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the
instantiation or location of its dependencies on its own by using direct construction of classes or the
Service Locator pattern.

面向对象编程时,对象之间的关系有一下三种

  • 依赖:一个类A调用了类B
  • 继承:is a 关系
  • 聚合:has a 关系

3. Bean

在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是由Spring IoC容器实例化、组装和管理的对象。否则,bean只是应用程序中的众多对象之一。bean及其之间的依赖关系反映在容器使用的配置元数据中。

In Spring, the objects that form the backbone of your application and that are managed by the

Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and
otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in
your application. Beans, and the dependencies among them, are reflected in the configuration
metadata used by a container.

4. AOP(Aspect-oriented Programming)

Aspect-oriented Programming (AOP) complements Object-oriented Programming (OOP) by
providing another way of thinking about program structure. The key unit of modularity in OOP is
the class, whereas in AOP the unit of modularity is the aspect. Aspects enable the modularization of
concerns (such as transaction management) that cut across multiple types and objects. (Such
concerns are often termed “crosscutting” concerns in AOP literature.)
One of the key components of Spring is the AOP framework. While the Spring IoC container does
not depend on AOP (meaning you do not need to use AOP if you don’t want to), AOP complements
Spring IoC to provide a very capable middleware solution.

AOP和OOP的关系:
AOP 解决 OOP 中遇到的一些问题.是 OOP 的延续和扩展.
AOP 可以进行权限校验,日志记录,性能监控,事务控制.

5,容器(Container)

org.springframework.context.ApplicationContext接口表示Spring IoC容器,负责实例化、配置和组装bean。容器通过读取配置元数据获取关于要实例化、配置和组装哪些对象的指令。配置元数据用XML、Java注释或Java代码表示。它允许您表达组成应用程序的对象以及这些对象之间丰富的相互依赖关系。

The org.springframework.context.ApplicationContext interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata. The configuration metadata is represented in XML, Java annotations, or Java code. It lets you express the objects that compose your application and the rich interdependencies between those objects.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容