JavaEE(八):Spring

一、简介

    Spring Framework(简称Spring)J2EE应用程序框架,它是针对Bean的生命周期进行管理的轻量级容器(Lightweight container)。Spring是一个开源的控制反转面向切面的容器框架,主要目的是简化企业开发。Spring配置文件为applicationContext.xml。

二、控制反转(IOC)

    所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。其主要实现为

依赖查找(Dependency Lookup):容器提供回调接口和上下文环境给组件。EJB和Apache Avalon都使用这种方式。

依赖注入(Dependency Injection):组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。

目前主要使用依赖注入。DIIOC是差不多的概念。IOC侧重于原理,DI侧重于实现。

DI三种方式:

1、setter注入
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
    <!-- 写法一 -->
    <!-- <property name="UserDao" ref="userDaoMyBatis"></property> -->
    <!-- 写法二 -->
    <property name="userDao" ref="userDaoMyBatis"></property>
</bean>

<!-- 注册mybatis实现的dao -->
<bean id="userDaoMyBatis" class="com.lyu.spring.dao.impl.UserDaoMyBatis"></bean>
public class UserService implements IUserService {

    private IUserDao userDao1;

    public void setUserDao(IUserDao userDao1) {
        this.userDao1 = userDao1;
    }

    public void loginUser() {
        userDao1.loginUser();
    }

}
2、构造器注入
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
    <constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
<!-- 注册jdbc实现的dao -->
<bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>
public class UserService implements IUserService {

    private IUserDao userDao;

    public UserService(IUserDao userDao) {
        this.userDao = userDao;
    }

    public void loginUser() {
        userDao.loginUser();
    }

}
3、基于注解注入(使用较多)

主要有四种注解可以注册bean,每种注解可以任意使用,只是语义上有所差异:

  1. @Component:可以用于注册所有bean
  2. @Repository:主要用于注册dao层的bean
  3. @Controller:主要用于注册控制层的bean
  4. @Service:主要用于注册服务层的bean

描述依赖关系主要有两种:

  • @Resource:java的注解,默认以byName的方式去匹配与属性名相同的bean的id,如果没有找到就会以byType的方式查找,如果byType查找到多个的话,使用@Qualifier注解(spring注解)指定某个具体名称的bean。
@Resource
@Qualifier("userDaoMyBatis")
private IUserDao userDao;

public UserService(){

}
  • @Autowired:spring注解,默认也是以byName的方式去匹配与属性名相同的bean的id,如果没有找到,就通过byType的方式去查找,如果查找到多个,用@Qualifier注解限定具体使用哪个。
@Autowired
@Qualifier("userDaoJdbc")
private IUserDao userDao;

三、面向切面(AOP)

    AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。

使用场景:

  • Authentication 权限
  • Caching 缓存
  • Context passing 内容传递
  • Error handling 错误处理
  • Lazy loading 懒加载
  • Debugging  调试
  • logging, tracing, profiling and monitoring 记录跟踪 优化 校准
  • Performance optimization 性能优化
  • Persistence  持久化
  • Resource pooling 资源池
  • Synchronization 同步
  • Transactions 事务

相关概念:

  • 方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的 Advisor或拦截器实现。
  • 连接点(Joinpoint): 程序执行过程中明确的点,如方法的调用或特定的异常被抛出。
  • 通知(Advice): 在特定的连接点,AOP框架执行的动作。Spring中定义了五个advice: 前置通知(Before),后置通知(After), 返回通知(After-returning),异常通知(After-throwing)环绕通知(Around)
  • 切入点(Pointcut): 指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点:例如,使用正则表达式。 Spring定义了Pointcut接口,用来组合MethodMatcher和ClassFilter,可以通过名字很清楚的理解, MethodMatcher是用来检查目标类的方法是否可以被应用此通知,而ClassFilter是用来检查Pointcut是否应该应用到目标类上
  • 引入(Introduction): 添加方法或字段到被通知的类。 Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现 IsModified接口,来简化缓存。Spring中要使用Introduction, 可有通过DelegatingIntroductionInterceptor来实现通知,通过DefaultIntroductionAdvisor来配置Advice和代理类要实现的接口
  • 目标对象(Target Object): 包含连接点的对象。也被称作被通知或被代理对象。POJO
  • AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
  • 织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。

1、实现(基于注解)

LogAspect中的代码

/** 
 * 1、告诉ioc这个组件的存在 
 * 2、告诉ioc这是一个切面使用@Aspect 
 * @author syl 
 * 
 */  
@Aspect  
@Component  
public class LogAspect {  
      
    /** 
     * try{ 
     *      @Before前置通知 
     *      method.invoke(); 
     *      @AfterRunning返回通知 
     * }catch(e){ 
     *      @AfterThrowing:异常通知, 
     * } 
     * @After 
     * 
     * 告诉Spring这些放在都在那个方法的哪个位置执行 
     * 1)、告诉位置 
     [1]@Before:前置通知,在方法执行之前执行 
     [2]@After:后置通知,在方法执行最终结束之后执行。 
        如果没异常 
     [3]@AfterRunning:返回通知,在方法返回结果之后执行 
     [4]@AfterThrowing:异常通知,在方法抛出异常之后执行 
 
 
    1、编写切入点表达式,来告诉spring是切入哪个方法的这个位置 
     */  
    @Before(value="execution(public * *.add(int, int))")  
    public void logStart(){  
    System.out.println("AOP日志,方法开始");  
    }  
      
    @After(value="execution(public * *.add(int, int))")  
    public void logEnd(){  
    System.out.println("AOP日志,方法最终结束");  
    }  
      
    @AfterThrowing(value="execution(public * *.add(int, int))")  
    public void logException(){  
    System.out.println("AOP日志,方法出现异常");  
    }  
      
    @AfterReturning(value="execution(public * *.add(int, int))")  
    public void logReturn(){  
    System.out.println("AOP日志,方法正常执行");  
    }  

applicationContext中的内容

<!--1、自动扫描所有的组件  -->  
<context:component-scan base-package="com.atguigu"></context:component-scan>  
<!--2、开启基于注解的aop功能  -->  
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>  
<!--  
 0)、被代理对象也得先加入到ioc中  
 1)、编写日志切面,并加入到ioc中,@Component @Aspect  
 2)、给切面编写通知方法。  
 3)、加上何时何地切入的注解。切入点表达式  
 4)、开启基于注解的aop功能即可  
 -->  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值