Spring-05 使用注解开发

使用注解开发

1.项目准备

在spring4之后,想要使用注解形式,必须得要引入aop的包5

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.3</version>
</dependency>

在配置文件当中,还得要引入一个context约束

<?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>

2.Bean实现

我们之前都是使用 bean 的标签进行bean注入,但是实际开发中,我们一般都会使用注解!

1、配置扫描哪些包下的注解

<context:component-scan base-package="pojo"/>

2、在指定包下编写类,增加注解

// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
@Component("user")
public class User {
public String name = "zc";
}

3.测试

    @Test
public void UserTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = (User) applicationContext.getBean("user");
System.out.println(user.name);
}

3.属性注入

3.1 不提供set方法

可以不提供set方法,直接在属性名上添加@value(“xxx”)

@Component("user")
public class User {
// 相当于配置文件中 <property name="name" value="秦疆"/>
@Value("zc")
public String name;
}

测试结果成功

3.1 提供了set方法

如果提供了set方法,在set方法上添加@value(“xxx”)

@Component("user")
public class User {
public String name; @Value("zc")
public void setName(String name) {
this.name = name;
}
}

测试结果成功

4.衍生注解

我们这些注解,就是替代了在配置文件当中配置步骤而已!更加的方便快捷!

@Component三个衍生注解

为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。

  • @Controller:web层
  • @Service:service层
  • @Repository:dao层

写上这些注解,就相当于将这个类交给Spring管理装配了!

作用域

@scope

  • singleton:默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
  • prototype:多例模式。关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收
@Component("user")
@Scope("prototype")
public class User {
@Value("zc")
public String name;
}

总结

XML与注解比较

  • XML可以适用任何场景 ,结构清晰,维护方便
  • 注解不是自己提供的类使用不了,开发简单方便

xml与注解整合开发 :推荐最佳实践

  • xml管理Bean
  • 注解完成属性注入
  • 使用过程中, 可以不用扫描,扫描是为了类上的注解
<context:annotation-config/>

作用:

  • 进行注解驱动注册,从而使注解生效
  • 用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册
  • 如果不扫描包,就需要手动配置bean
  • 如果不加注解驱动,则注入的值为null

5.使用java的方式配置Spring

我们现在要完全不使用spring的xml配置,全权交给java来做。

5.1 实体类

@Controller
public class UserT {
// 属性的注入
@Value("zcT")
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}

5.2 配置类

@Configuration:本质上也是一个Controller,也会被spring托管,注册到容器中

@Configuration:表示这是一个配置类,和之前的beans.xml的功能一样的

@ComponentScan:表示组件的扫描

@import:导入其他的配置类

@Bean:表示注册一个bean

@Configuration
@ComponentScan("pojo")
public class MyConfig {
// 方法的名字即是bean中的id
// 方法的返回值就是bean中的class
@Bean
public UserT getUserT(){
return new UserT(); // return就是返回要注入到bean中的对象
}
}

5.3 测试

    @Test
public void UserTTest(){
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
UserT userT = (UserT) context.getBean("getUserT");
System.out.println(userT.toString());
}

代理模式

为什么要学习代理模式,因为AOP的底层机制就是动态代理。

代理模式:

  • 静态代理
  • 动态代理

1.静态代理

角色分析

  • 抽象角色 : 一般使用接口或者抽象类来实现
  • 真实角色 : 被代理的角色
  • 代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作
  • 客户 : 使用代理角色来进行一些操作

1.1 案例分析

1.1.1 接口类
public interface Rent {
public void rent();
}
1.1.2 实体类
//房东
public class Host implements Rent{
public void rent() {
System.out.println("出租房子");
}
}
//代理类
public class Proxy implements Rent{
private Host host;
public Proxy(){
}
public Proxy(Host host){
this.host = host;
}
// 因为要帮房东租房子,所以代理也要实现租房子
public void rent() {
host.rent();
}
//看房
public void seeHouse(){
System.out.println("带房客看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
}
}
1.1.3 测试实体类
public class Client {
public static void main(String[] args) {
// 房东要租房
Host host = new Host();
// 中介帮房东
Proxy proxy = new Proxy(host);
// 去找中介
proxy.rent();
}
}

分析:在这个过程中,你直接接触的就是代理类(Proxy),就如同现实生活中的样子,你看不到房东,但是你依旧通过中介,租到了房东的房子,这就是所谓的代理模式。

静态代理的好处:

  • 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .
  • 公共的业务由代理来完成 . 实现了业务的分工 ,
  • 公共业务发生扩展时变得更加集中和方便 .

缺点 :

  • 类多了 , 多了代理类 , 工作量变大了 . 开发效率降低 .

我们在不改变原来的代码的情况下,实现了对原有功能的增强,这是AOP中最核心的思想。

2.动态代理

  • 动态代理的角色和静态代理的一样 .

  • 动态代理的代理类是动态生成的,静态代理的代理类是我们提前写好的

  • 动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理

    • 基于接口的动态代理----JDK动态代理
    • 基于类的动态代理--cglib
    • 现在用的比较多的是 javasist 来生成动态代理
    • 我们这里使用JDK的原生代码来实现

2.1 JDK的动态代理需要了解两个类

核心 : InvocationHandler 和 Proxy

【InvocationHandler:调用处理程序】

Object invoke(Object proxy, 方法 method, Object[] args);
//参数
//proxy - 调用该方法的代理实例
//method -所述方法对应于调用代理实例上的接口方法的实例。方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
//args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。

【Proxy : 代理】

//生成代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}

2.2 案例分析

2.2.1 接口类
//抽象角色:租房
public interface Rent {
public void rent();
}
2.2.2 实体类
//房东
public class Host implements Rent{
public void rent() {
System.out.println("出租房子");
}
}
2.2.3 代理类
public class ProxyInvocationHandler implements InvocationHandler {
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}
// proxy : 代理类 method : 代理类的调用处理程序的方法对象.
// 处理代理实例上的方法调用并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//核心:本质利用反射实现!
Object result = method.invoke(rent, args);
fare();
return result;
}
//看房
public void seeHouse(){
System.out.println("带房客看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
}
}
2.2.4 测试实体类
public class Client {
public static void main(String[] args) {
//真实角色
Host host = new Host();
//代理实例的调用处理程序
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setRent(host); //将真实角色放置进去
Rent proxy = (Rent)pih.getProxy(); //动态生成对应的代理类
proxy.rent();
}
}

一个动态代理 , 一般代理某一类业务 , 一个动态代理可以代理多个类,代理的是接口

2.3 动态代理的好处

静态代理有的它都有,静态代理没有的,它也有!

  • 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .
  • 公共的业务由代理来完成 . 实现了业务的分工 ,
  • 公共业务发生扩展时变得更加集中和方便 .
  • 一个动态代理 , 一般代理某一类业务
  • 一个动态代理可以代理多个类,代理的是接口!

个人博客为:

MoYu's Github Blog

MoYu's Gitee Blog

Spring-05 使用注解开发的更多相关文章

  1. Spring笔记04_AOP注解开发_模板_事务

    目录 1. Spring基于AspectJ的注解的AOP开发 1. 1 SpringAOP的注解入门 1.2 Spring的AOP的注解通知类型 1.2.1 @Before:前置通知 1.2.2 @A ...

  2. spring boot纯注解开发模板

    简介 spring boot纯注解开发模板 创建项目 pom.xml导入所需依赖 点击查看源码 <dependencies> <dependency> <groupId& ...

  3. Spring的IOC注解开发入门1

    基本知识点如下: 引入注解约束,配置组件扫描 类上的注解: @Conponent  @Controller @Service @Repository 普通属性的注解   @value 对象属性的注解  ...

  4. Spring笔记13--SSH--全注解开发

    SSH全注解开发: (1) 在Action类中添加注解,实现Struts2的注解开发(@NameSpace.@ParentPackage.@Action...) package com.tongji. ...

  5. Spring的IOC注解开发入门2

    注解方式设置属性的值 在我们IOC基于xml属性注入的方式中有(一般推荐set方法) 构造方法注入普通值:<constructor-arg>的使用 set方法注入普通值:<prope ...

  6. spring MVC之注解开发控制器(二)

    开发表单控制器 在传统的Spring MVC开发方法中,是通过扩展SimpleFormController类来创建简单的表单控制器.这样就定义了基本的表单处理流程,并允许通过覆盖几个生命周期方法来定制 ...

  7. spring 使用@AspectJ注解开发Spring AOP

    选择切点 Spring是方法级别的AOP框架,而我们主要也是以某个类的某个方法作为切点,用动态代理的理论来说,就是要拦截哪个方法织入对应AOP通知. 代码清单:打印角色接口 package com.s ...

  8. Annotation(三)——Spring注解开发

    Spring框架的核心功能IoC(Inversion of Control),也就是通过Spring容器进行对象的管理,以及对象之间组合关系的映射.通常情况下我们会在xml配置文件中进行action, ...

  9. Spring注解开发系列专栏

    这个系列主要是讲Spring注解的使用,可以为后面SpringBoot的学习带来一定的帮助.我觉得从Spring直接过度到SpringBoot还是有点快,还是得需要一个演变的过程.从Spring开发, ...

  10. Spring 注解开发

    目录 注解开发简介 常用注解 启用注解功能 bean 定义:@Component.@Controller.@Service.@Repository bean 的引用类型属性注入:@Autowired. ...

随机推荐

  1. Educational Codeforces Round 30

    Educational Codeforces Round 30  A. Chores 把最大的换掉 view code #pragma GCC optimize("O3") #pr ...

  2. Codeforces Round #648 (Div. 2) E. Maximum Subsequence Value(鸽巢原理)

    题目链接:https://codeforces.com/problemset/problem/1365/E 题意 有 $n$ 个元素,定义大小为 $k$ 的集合值为 $\sum2^i$,其中,若集合内 ...

  3. hdu4719 Oh My Holy FFF 线段树维护dp

    题意:给你一个长度为n的数组v,你需要把这个数组分成很多段,你需要保证每一段的长度不能超过k我们设一共有m段,每一段右边界那个数为bi那么我们要使得sum(bi*bi-b(i-1))最大 (1< ...

  4. 【bzoj 1202】[HNOI2005] 狡猾的商人(图论--带权并查集+前缀和)

    题意:一个账本记录了N个月以来的收入情况,现在有一个侦探员不同时间偷看到M段时间内的总收入,问这个账本是否为假账. 解法:带权并查集+前缀和.   判断账本真假是通过之前可算到的答案与当前读入的值是否 ...

  5. Codeforces Round #689 (Div. 2, based on Zed Code Competition) E. Water Level (贪心好题)

    题意:你在一家公司工作\(t\)天,负责给饮水机灌水,饮水机最初有\(k\)升水,水的范围必须要在\([l,r]\)内,同事每天白天都会喝\(x\)升水,你在每天大清早可以给饮水机灌\(y\)升水,问 ...

  6. ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2015) G. It is all about wisdom (二分,单源最短路)

    题意:有\(n\)个点,\(m\)条边,只有当你的智力值大于这条边的\(w\)才能走,问在花费不超过\(k\)的情况下,从\(1\)走到\(n\)的所需的最小智力值. 题解:这题比赛为什么没想出来呢? ...

  7. oslab oranges 一个操作系统的实现 实验一

    实验目的: 搭建基本实验环境,熟悉基本开发与调试工具 对应章节:第一.二章 实验内容: 1.认真阅读章节资料 2.在实验机上安装virtualbox,并安装ubuntu 3.安装ubuntu开发环境, ...

  8. h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated

    Reference 问题 ... h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype ...

  9. 24 WAYS to impress your friends

    24 WAYS to impress your friends 24 ways is the advent calendar for web geeks. For twenty-four days e ...

  10. Apple CSS Animation All In One

    Apple CSS Animation All In One Apple Watch CSS Animation https://codepen.io/xgqfrms/pen/LYZaNMb See ...