您现在的位置是:首页 >技术杂谈 >使用注解存储Bean对象网站首页技术杂谈
使用注解存储Bean对象
日升时奋斗,日落时自省
目录
前面博客告诉了问如何创建Spring和使用,但是存储方式还是比较复杂的,如果要使用的多个对象,那不得要多个Bean标签,几时几百个类进行处理(冗余代码太多)
现在有了注解,能够放方便的存储和获取Bean对象,在Spring中想要更简单的存储和获取对象的核心是使用注解
注解是什么??
代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,从而做相对应的处理。
注解优势:简化代码,降低耦合性,提高执行效率
1、存储Bean对象
这里还是需要Spring配置文件,配置文件(我们在resources文件下创建一个Spring配置文件spring-config.xml)还是上一个博客中提供的
<?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:content="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 https://www.springframework.org/schema/context/spring-context.xsd">
<content:component-scan base-package="com.bit.service"></content:component-scan>
</beans>
这次就不需要删除什么了
来看一下,这里要怎么使用这个spring配置文件
现在问题来了:有那些相关注解会被使用到
1.1、五大类注解
@Controller注解:表示一个处理HTTP请求的控制器对象,控制器,验证用户请求的数据正确性(安全保证系统)
注:如果有人恶意访问(尝试攻击或者测试),就会被拦截下来,接收前端传递的请求,查看前端的信息是否正确
@Service:服务类为其他组件提供了一种复用业务逻辑的方法,能够减少重复代码的编写,提高代码的可维护性(客服中心);重点在于编排和调度具体的执行方法
@Repository:持久层 :持久层是指与数据库有交互的逻辑层方便在Service层中进行调用
@Component:组件(是个工具类)用于标识一个类作为一个可被扫描的组件
@Configuration:配置项:(项目中的一些配置)在Spring容器中作为一个配置类,并且被用来替代XML配置文件
1.2、添加注解存储Bean对象(Controller)
此处是先以Controller注解作为演示的
启动类具体上没有很大的变化,但是参数上有些许变化
1.3、Bean的命名规则
类似id 参数名称是有一套规则的(接下来来解释)
那现在就拿这个规则来试一下开头如果是两个大写字符的类,在规则下,能不能跑起来
这里创建一个类SController来演示
总结bean的name规则:
<1>如果类名前两个字符都是大写字母,那bean的name就不需要改变,就写原类名就可以
<2>如果类名前两个字符只有第一给字符是大写字母,那bean的name只需要将第一个字符小写即可
1.4、其他类注解演示
前面使用了@Controller进行类对象注入Spring,那Service,Repository,Component,Configuration这些注解也是可以的
下面就简单的操作一下其他的类注解
注解的真正用途:其他注解也能实现,并且实现注解还都是Component注解,这样重复出现也不起不到什么作用了,这些类注解主要目的是为了分层的
1.5、为什么需要五大类注解
这里的分层就和开始针对注解的作用,让别的人一看就能看懂你的项目那部分是干什么的
<1>@Controller:表示就是业务逻辑层
<2>@Service:服务层(针对端口等)
<3>@Repository:持久层
<4>@Configuration:配置层
此处拿阿里巴巴的分层结构给友友们解释
1.5.1、JavaEE标准分层
Java标准分层 ,可以分为三层,有的地方将分层分为了四层,这里都会做以解释
JavaEE标出分层至少被分为三层(此处演示三层)
<1>控制层
控制层负责处理用户请求并将请求转发给业务逻辑层,同时还需要对请求参数进行验证和过滤等处理,并将处理结果封装成响应对象返回给客户端
<2>服务层
服务层具有独立性和可重用性,可以被多个控制器共用,提高代码的复用性和可维护性。
<3>数据持久层
控制层负责处理用户请求并将请求转发给业务逻辑层,同时还需要对请求参数进行验证和过滤等处理,并将处理结果封装成响应对象返回给客户端
1.5.2、实例分层结构
这里实例分层结构具体拿阿里巴巴的为例(还是很有权威的)
为什么会有业务逻辑和通用逻辑层,都是逻辑层,出现两个干什么,主要区别在于操作什么数据
通用业务逻辑层:
对第三方平台封装的层,预处理返回结果及转化异常信息;
对 Service 层通用能力的下沉,如缓存方案、中间件通用处理;
与 DAO 层交互,对多个 DAO 的组合复用。
也就是不需要什么操作都要通过Service层
1.5.3、分层领域规约
以下引用部分的区分都是来自于《Java开发手册-嵩山版》
<1> DO( Data Object): 此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
<2> DTO( Data Transfer Object):数据传输对象, Service 或 Manager 向外传输的对象。
<3> BO( Business Object):业务对象, 可以由 Service 层输出的封装业务逻辑的对象。
<4> Query:数据查询对象,各层接收上层的查询请求。 注意超过 2 个参数的查询封装,禁止使用 Map 类来传输。
<5> VO( View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象
给出以上分层是为了类名使用的
我们代码中也是这么分层,基本上是依照这样的分层格式,我门写代码也将这些细致化分为四层也就是四个包
service包,entity包,component包,controller包(分别写什么代码)
(1)service层:是业务逻辑层,包中存放的不是具体业务类,而是一些接口
(2)entity层:放置一个个实体,及其相应的set、get方法。如果想要对数据库进行一些操作的话,就要先写entity层(也有叫做model或者models都是一个东西,只是派系不同而已)
(3)component层:存放一些组件
(4)controller层:只接收数据,然后校验数据,校验合法性和准确性,(比如接收用户信息)
对象命名规范:
<1> 基本对象(对应数据库中的一张表):表名:Userinfo 或者 UserinfoEntity 又或者使用UserinfoDo等
<2> 扩展对象:使用Userinfo / UserinfoOtherVO / Userinfo...VO
2、@Bean方法注解
2.1、配合类注解使用
有类注解使用,针对方法注解顾名思义:注解添加到方法上(直接开始演示)
注:从@Bean方法注解中,如何获取Bean对象,直接写方法名称就行(不用加任何修饰)
2.2、重命名问题(同类下)
涉及到:@Bean对象的参数
如果@Bean方法注解如果重名了需要怎么办(情况特殊,基本不能改的情况下,这里就可以给该方法起一个别名)
这里假设刚刚user1 这个名字已经用不了了,而且因为特殊原因还不能修改的
注:
<1>起了别名以后的方法 ,只能使用别名来获取,不能再使用本名来获取
<2>别名可以起多个
2.3、重命名问题(不同类下)
主要扩展一个 新的注解 : @Order(参数)
如果在不同类下有相同方法名,获取Bean对象的时候,是不会报错,执行代码也是遵循从上到下的(这里稍作演示)
注:@Order(参数) 该注解的参数 越大加载就越滞后,所以可通过该注解针对不同类重命名的
3、对象注入
有以下3种方法
<1> 属性注入
<2> Setter注入
<3> 构造方法注入
下面使用Service类注入到Controller类中
3.1、属性注入
提示:对象注入需要使用到@Autowired注解,所以属性注入也需要
在属性上方加上@Autowired注解
优点:代码简单
缺点:
<1> 不能给final修饰的变量进行注入
<2> 兼容性较差:只适用于IoC容器
<3> 风险:容易违背单一设计原则
3.2、Setter注入
使用一个方法注入 ,叫做Setter注入 给一个注入方法上方加上一个@Autowired注解
启动类没有改变,还是原来的启动类(这里只是不同的注入方式,名没有改变类名)
优点:符合单一变量原则(固定格式避免违背单一变量原则)
缺点:
<1>不能给final修饰的属性进行对象注入
<2>Setter注入的属性容易被改变
其实我感觉这个是可以避免一点点的,让该方法使用private权限修饰,启动类就访问不到了
3.3、构造方法注入
优点:
<1>可以注入一个final修饰的对象
<2>注入对象不会进行改变
<3>构造方法可以确定对象的初始化
<4>通用性很高
这里主要依赖于java的基本语法
<1>final修饰的属性在开始创建时就需要赋值
<2>final修饰的属性如果在开始的时候没有进行赋值,那就需要构造方法来给属性赋值才能使用
3.4、@Resource注入(搭配)
@Resource注解也是可以有@Autowired注解的作用,进行属性注入,Setter注入,但是它不能给构造方法上加@Resource注解,会报错(不支持)
这里简单的使用一下,其实就是注解替换了将@Resource注解替了@Autowired注解
那都有@Autowired注解还要@Resource注解干什么??
3.5、@Resource与@Autowired区别
<1>来源不同:@Autowired来源于SPring,而@Resource来源于JDK的注解
<2>适用参数不同,@Autowired注解没有参数就是必须进行对象注入的,@Resource注解就不一样了,支持更多的参数设置,根据名称获取Bean对象(这里我们来看一下Resource注解中有多少参数可以使用)
有多个参数可以配合特殊情况使用,大部分情况下两者都是可以使用的(也就意味着可以交替使用)
<3>@Autowired可以搭配使用三种对象注入方式,而Resource注解只能搭配使用两种对象注入方式,不能用于构造函数注入