Spring-Day03-注解注入&AOP入门-作业

  • IOC(DI) —— 注解
    • 注解入门:
      • 在applicationContext.xml中引入context约束
        • 打开spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html中的xsd-configuration.html文件,搜索context schema,找到配置内容复制之,配置内容如下:
<?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: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/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
      • 开启扫描组件:扫描配置的包名下的所有子孙包的注解
<!-- 开启扫描组件:扫描配置的包名下的所有子孙包的注解 -->
<context:component-scan base-package="kong.spring.day03.dao"/>
      • 创建UserDao接口
package kong.spring.day03.dao;

public interface UserDao {
    public void save();
}
      • 创建UserDao接口的实现类UserDaoImpl
package kong.spring.day03.dao;

import org.springframework.stereotype.Component;

// 使用注解的方式将对象交给Spring管理
// 相当于在xml中配置<bean name="userDao" class="kong.spring.day03.dao.UserDaoImpl"></bean>
@Component(value="userDao") 
public class UserDaoImpl implements UserDao{

    @Override
    public void save() {
        System.out.println("我是保存方法。。。save");
    }
}
      • 创建测试类
package kong.spring.day03.test;

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 kong.spring.day03.dao.UserDao;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestDemo {
    
    // 手动装配在UserDaoImpl中使用注解注入的userDao对象
    @Resource(name="userDao")
    private UserDao userDao;
    
    @Test
    public void testIocAnnotation01() {
        // 测试能否成功调用使用注解注入的userDao对象的save方法
        userDao.save();
    }
}
      • 测试如果:在UserDaoImpl中使用注解注入的userDao对象能正常使用并调用其save方法

        

    • 使用注解进行属性注入
      • 使用注解Value("属性值")进行注入
        • 可以在类属性上注入
        • 也可以在set方法上注入
      • 使用注解进行属性注入的类代码如下:
package kong.spring.day03.dao;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

// 使用注解的方式将对象交给Spring管理
// 相当于在xml中配置<bean name="userDao" class="kong.spring.day03.dao.UserDaoImpl"></bean>
@Component(value="userDao") 
public class UserDaoImpl implements UserDao{
    
    // 没有set方法也能在属性上成功注入,但有set方法时,在属性上注入或set方法注入都可以,并不是“在有SET方法的时注解 @value("值") 必须添加在SET方法上”!
    @Value("NulluN_property")
    private String name;
    
    // 也可以在set方法上注入属性值
    //@Value("NulluN_set")
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void save() {
        System.out.println("我是save保存方法;" + "name属性注入值为:" + name);
    }
}
      • 测试代码如下:
    // 测试使用注解进行属性注入
    @Test
    public void testIocDiAnnotation01() {
        // 通过调用userDao对象的save方法测试注解注入属性值是否成功
        userDao.save();
    }
      •  测试结果:

        

    • 根据MVC分层思想,由@Component衍生出来三种在其他类上的注解:
      • @Controller:控制(web)层注解
      • @Service:服务层注解
      • @Repository:数据(持久/dao)层注解
    • 测试在服务层使用@Service注解,同时测试使用@Autowired搭配@Qualifier或@Resource注解进行对象类型注入
      • 创建UserService接口
package kong.spring.day03.service;

public interface UserService {
    
    public void save();
}
      • 创建UserService接口的实现类UserSeviceImpl
package kong.spring.day03.service;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import kong.spring.day03.dao.UserDao;

//服务层类注解
@Service("userService")
public class UserSeviceImpl implements UserService {

 // 使用@Autowired搭配@Qualifier进行对象类型注入

 // 注意:可以只使用@Autowired来自动装配userDao对象;@Qualifier注解不能单独使用,单独使用会报错!

  // 即@Qualifier需要和@Autowired搭配使用
  //@Autowired
  //@Qualifier(value = "userDao")

  // 也可使用@Resource注解进行对象类型注入
  @Resource(name = "userDao")

  private UserDao userDao;
    
  @Override
  public void save() {
     userDao.save();
  } 
}
      • 测试服务层注解是否成功使用
    // 测试使用@Service注解将服务层对象交给Spring管理
    @Test
    public void testIocServiceAnnotation() {
        // 通过调用UserService对象的save方法,进而通过UserDao对象调用其save方法,测试UserDao的注解属性值注入是否成功
        us.save();
    }
      • 测试结果:服务层注解成功将服务层对象交给Spring管理;同时,服务层使用使用@Autowired搭配@Qualifier注解成功将dao层的userDao对象注入到服务层,从而服务层对象成功调用dao层save方法

        

    • 测试在dao层使用@Repository注解
      • UserDaoImpl代码基本同上,在类上使用@Repository("userDao")注解将userDao对象交给Spring管理
      • 测试代码:
    // 测试dao层使用@Repository注解
    @Test
    public void testIocRepositoryDiAnnotation() {
        // 通过调用userDao对象的save方法测试用@Repository注解是否成功将对象交给Spring管理
        UserDao.save();
    }
      • 测试结果:成功使用@Repository注解将userDao对象交给Spring管理

        

    • Bean生命周期注解
      • 创建实例后执行方法注解:@PostConstruct

      • 销毁实例前执行方法注解:@PreDestroy

      • 测试代码:
    @Resource(name = "userService")
    private UserService us;
    // 测试Bean生命周期注解
    @Test
    public void testBeanLifeCycleAnnotation() {
        // 通过打印UserService对象来测试生命周期注解是否成功
        System.out.println(us);
    }
      • 测试结果:生命周期注解可以正常使用

        

    • @Scope("值")注解,默认为单例,注解在类上
      • 多例注解测试:

        

      • 测试类代码:
    @Resource(name = "userService")
    private UserService us;
    @Resource(name = "userService")
    private UserService us2;
    // 测试@Scope多例注解
    @Test
    public void testScopePrototypeAnnotation() {
        System.out.println(us);
        System.out.println(us2);
        System.out.println(us==us2);
    }
      • 测试结果:

        

  • XML与注解
    • 区别:
      • XML:结构清晰,维护方便
      • 注解:开发方便
    • XML与注解结合使用:
      • XML管理Bean
      • 属性注入用注解方式
      • 演示代码中XML配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.2.xsd">
    
    <!-- 开启扫描组件:扫描配置的包名下的所有子孙包的注解 -->
    <!-- 
        下面的开启扫描组件配置必须写,如果注释掉会报以下错误:
        org.springframework.beans.factory.BeanCreationException: Error creating bean with name 
        'kong.spring.day03.test.TestDemo': Injection of resource dependencies failed; nested 
        exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
        No bean named 'userDao' is defined
     -->
     <!-- 
         由于Bean对象已在XML中配置交给Spring管理,故不用以下扫描配置来扫描相关包下用注解交给Spring管理的对象了!
         也就是说可以将类中使用注解交给Spring管理的代码注释掉!
     -->
    <!-- <context:component-scan base-package="kong.spring.day03.dao"/>
    <context:component-scan base-package="kong.spring.day03.service"/> -->
    
    <!-- 当不需要使用扫描类,但需要使用注解方式实现属性注入时,用以下配置 -->
    <!-- 经测试:以下配置也可以不用!属性一样可以成功使用注解方式注入 -->
    <!-- <context:annotation-config/> -->
    
    <!-- XML与注解结合 -->
    <!-- XML管理Bean -->
    <bean name="userDao" class="kong.spring.day03.dao.UserDaoImpl"/>
    <bean name="userService" class="kong.spring.day03.service.UserServiceImpl"/>
    <bean name="carService" class="kong.spring.day03.service.CarServiceImpl"/>
</beans>
      • UserServiceImpl类代码如下:使用注解实现属性注入
package kong.spring.day03.service;
import javax.annotation.Resource;import kong.spring.day03.dao.UserDao;

public class UserServiceImpl implements UserService {

    @Resource(name = "userDao")
    private UserDao userDao;
    
    @Resource(name = "carService")
    private CarServiceImpl carService;
    
    @Override
    public void save() {
        carService.say();
        userDao.save();
    }
}
      • UserDaoImpl类代码如下:使用注解实现属性注入
package kong.spring.day03.dao;

import org.springframework.beans.factory.annotation.Value;
public class UserDaoImpl implements UserDao{
    
    @Value("NulluN_property")
    private String name;
    
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void save() {
        System.out.println("我是save保存方法;" + "name属性注入值为:" + name);
    }

}
      • CarServiceImpl类代码如下:
package kong.spring.day03.service;

public class CarServiceImpl {
    
    public void say() {
        System.out.println("我是擎天柱!");
    }
}
      • 测试类代码如下:
    // 手动装配在XML中配置的userService对象
    @Resource(name = "userService")
    private UserService us;
    
    // 测试XML与注解结合:Bean在XML中配置,属性依赖注入使用注解在类中实现
    @Test
    public void testXmlWithAnnotation() {
        us.save();
    }
      • 测试结果如下:XML与注解结合成功实现Bean交给Spring管理与属性注入

        

  • Spring AOP:
    • AOP:面向切面编程,是OOP的拓展延伸,解决OOP开发中遇到的问题
    • AOP:横向抽取机制(代理机制)取代了OOP纵向继承
    • Spring底层实现AOP原理:动态代理
      • JDK的动态代理
      • Cglib动态代理(第三方代理技术)
      • Spring有自己实现AOP的方式,但被弃用,Spring目前实现AOP使用的是第三方的一个AOP框架,叫“AspectJ”
    • AOP常用相关术语:
      • 连接点(joinpoint):目标对象中,所有可以增强的方法,如下面例子中的CarInfoImpl类中的save方法
      • 切入点(pointcut):目标对象中,已经增强的方法,如下面例子中CarInfoImpl类中的save方法被增强了
      • 通知(advice):增强的代码,如下面例子中CarInfoProxy类中的checkSave方法
      • 目标对象(target):被代理的对象,如下面例子中的CarInfoImpl类的对象
      • 织入(weave):将通知应用到切入点的过程
      • 代理(proxy):将通知织入到目标对象后形成代理对象
      • 切面(aspect):通知+切入点
    • AOP配置:
      • 切面(通知)类和目标类都交给Spring管理
      • 在applicationContext.xml中进行AOP配置前需要加入AOP约束规范,方法类同加入Beans和Context约束规范
      • 下面是applicationContext.xml的配置代码:
    <!-- AOP -->
    <!-- 目标类Bean配置 -->
    <bean name="carInfo" class="kong.spring.day03.aop.CarInfoImpl"/>
    <!-- 通知类配置 -->
    <bean name="carInfoProxy" class="kong.spring.day03.aop.CarInfoProxy"/>
    
    <!-- AOP配置 -->
    <aop:config>
        <!-- 配置切入点pointcut:配置需要增强的类中的哪些方法 -->
        <aop:pointcut expression="execution(* kong.spring.day03.aop.CarInfo.save(..))" id="carPointcut"/>
        <!-- 配置切面 -->
        <!-- 配置引用的切面类 -->
        <aop:aspect ref="carInfoProxy">
            <!-- 在切入点carPointcut中配置前置通知,即执行目标类中方法前要调用以下的切面类中checkSave方法 -->
            <aop:before method="checkSave" pointcut-ref="carPointcut"/>
        </aop:aspect>
    </aop:config>
      • 目标类的接口CarInfo 
package kong.spring.day03.aop;

public interface CarInfo {
    
    public void save();
}
      • 目标类CarInfoImpl 
package kong.spring.day03.aop;

/**
 * AOP目标类,也可叫“被代理类”,这个类最好是实现接口,而不是直接定义!否则控制台会出现四行很烦人的警告信息!
 * @author NulluN
 *
 */
public class CarInfoImpl implements CarInfo{
    
    public void save() {
        System.out.println("我买了一辆车,我要去浪。。。");
    }
}
      • 切面类CarInfoProxy
package kong.spring.day03.aop;

/**
 * AOP切面类,也叫“通知类”
 * @author NulluN
 *
 */
public class CarInfoProxy {
    
    public void checkSave() {
        System.out.println("我是增强的方法。。。");
    }
}
      • 测试代码:
    @Resource(name = "carInfo")
    private CarInfo carInfo;
    
    // 测试AOP前置通知
    @Test
    public void testAopBeforeAdvice() {
        carInfo.save();
    }
      • 测试结果:AOP配置正常,目标类方法被成功增强,且是前置通知类型

        

 

转载于:https://www.cnblogs.com/6nullun6/p/10306373.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值