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底层实现原理)


       
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.

你可能感兴趣的:(Spring框架(一))