注解
- @Resource注解实现自动注入 (反射)
- 代码块
- xml配置文件
- @Autowired注解实现自动化注入
- 代码块
- xml配置文件
- 扫描器-四个注解
- Dao层-@Repository
- Service层-@Service
- Controller层-@Controller
- 测试
- 任意类-@Component
- 常用注解示例-模拟用户登录
- 配置自动扫描的xml文件
- 实体类User
- dao层
- 消息模型对象MessageModel
- service层
- controller层
- 测试Test
- 第一种:用户密码不正确!
- 第二种:用户名或密码不能为空
- 第三种:用户名不存在!
- 第四种:登陆成功!
@Resource注解实现自动注入 (反射)
- 注解默认通过属性字段名称查找对应的bean对象(属性宇段名称与bean标签的id属性值一致)
- 如果属性字段名称不一样,则会通过类型 (CLass ) 类型
- 属性字段可以提供set方法 也可以不提供
- 注解可以声明在属性字段上 或 set 方法级别
- 可以设置注解的name属性,name属性值要与bean标签的id属性值一致(如果设置了name属性,则会按照name 属性查询bean对象)
- 当注入接口时,如果接口只有一个实现类,则正常实例化;如果接口有多个实现类,则需要使用name 属性指定需要被实例化的bean对象
代码块
//注入JavaBean对象
@Resource
private UserDao userDao;
public void test(){
System.out.println("UserService Test...");
userDao.test();
}
public static void main( String[] args )
{
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
UserService userService= (UserService) ac.getBean("userService");
userService.test();
}
xml配置文件
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启自动化注入(装配) -->
<context:annotation-config></context:annotation-config>
<!-- 配置bean对象-->
<bean id="userDao" class="com.svt.dao.UserDao"></bean>
<bean id="userService" class="com.svt.service.UserService"></bean>
</beans>
@Autowired注解实现自动化注入
- 注解默认使用类型 (CLass 类型) 查找bean 对象,与属性字名称没有关系
- 属性字可以提供set 方法 也可以不提供
- 注解可以声明在属性级别 或 set 方法级别
- 如果想要通过指定名称查bean对象,需要结合@Qualifier 使用(通过设置value 属性值查找,value 属性值要bean标签的id属性值保持一致)
代码块
@Autowired
private AccountDao accountDao;
public void test(){
System.out.println("UserDao Test...");
accountDao.test();
}
public static void main( String[] args )
{
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
AccountService accountService= (AccountService) ac.getBean("accountService");
accountService.test();
}
xml配置文件
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启自动化注入(装配) -->
<context:annotation-config></context:annotation-config>
<!-- account-->
<bean id="accountDao" class="com.svt.dao.AccountDao"></bean>
<bean id="accountService" class="com.svt.service.AccountService"></bean>
</beans>
推荐使用@Resource注解是属于J2EE的,减少了与Spring的耦合
原因 来源
来源不同:@Autowired 来自 Spring 框架,而 @Resource 来自于(Java)JSR-250
;
@Autowired功能虽说非常强大,但是也有些不足之处。比如它跟Spring强耦合了,如果换成了其他框架,功能就会失效。而@Resource是JSR-250提供的,它是Java标准,绝大部分框架都支持。
依赖查找的顺序不同:@Autowired 先根据类型再根据名称查询,而 @Resource 先根据名称再根据类型查询
;
Autowired默认按byType自动装配,而@Resource默认byName自动装配。
支持的参数不同:@Autowired 只支持设置 1 个参数,而 @Resource 支持设置 7 个参数
;
@Autowired只包含一个参数:required,表示是否开启自动准入,默认是true。而@Resource包含七个参数,其中最重要的两个参数是:name 和 type。
依赖注入的用法支持不同:@Autowired 既支持构造方法注入,又支持属性注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入
;
@Autowired能够用在:构造器、方法、参数、成员变量和注解上,而@Resource能用在:类、成员变量和方法上。
编译器 IDEA 的提示不同:当注入 Mapper 对象时,使用 @Autowired 注解编译器会提示错误,而使用 @Resource 注解则不会提示错误
。
@Autowired如果要使用byName,需要使用@Qualifier一起配合。而@Resource如果指定了name,则用byName自动装配,如果指定了type,则用byType自动装配。
扫描器-四个注解
设置了扫描器就只需要在xml文件内自动设置扫描范围,其余交给注解去实例化即可
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--
Spring IOC扫描器
作用:bean对象的统一管理,简化开发配置,提高开发效率。
1.设置自动化扫描的范围
如果bean对象未在扫描范围,即使声明了注解,也不会被实例化
2.在需要被实例化的JavaBean的类上添加指定的注解(注解声明在类级别) (bean对象的id属性默认是 类的首字母小写)
Dao层:
@Repository
Service层:
@Service
Controller层:
@Controller
任意类:
@Component
注:开发过程中建议按照规则声明注解。
-->
<!-- 设置自动化扫描范围-->
<context:component-scan base-package="com.svt"></context:component-scan>
</beans>
Dao层-@Repository
@Repository
public class TypeDao {
public void test(){
System.out.println("TypeDao Test...");
}
}
Service层-@Service
@Service
public class TypeService {
@Resource
private TypeDao typeDao;
public void test(){
System.out.println("TypeService Test...");
typeDao.test();
}
}
Controller层-@Controller
@Controller
public class TypeController {
@Autowired
private TypeService typeService;
public void test(){
System.out.println("TypeController Test...");
typeService.test();
}
}
测试
public static void main( String[] args )
{
ApplicationContext ac=new ClassPathXmlApplicationContext("spring02.xml");
// TypeDao typeDao= (TypeDao) ac.getBean("typeDao");
// typeDao.test();
// TypeService typeService= (TypeService) ac.getBean("typeService");
// typeService.test();
TypeController typeController= (TypeController) ac.getBean("typeController");
typeController.test();
}
任意类-@Component
不在三层架构内,另开了一个类,但是又需要实例化这个类,就可以用@Component注解
注:这个类需要包含在扫描器范围内,否则扫描不到也不会被实例化,最终报错
@Component
public class ProTest {
public void test(){
System.out.println("ProTest Test...");
}
}
public static void main( String[] args )
{
ApplicationContext ac=new ClassPathXmlApplicationContext("spring02.xml");
// TypeDao typeDao= (TypeDao) ac.getBean("typeDao");
// typeDao.test();
// TypeService typeService= (TypeService) ac.getBean("typeService");
// typeService.test();
TypeController typeController= (TypeController) ac.getBean("typeController");
typeController.test();
ProTest proTest= (ProTest) ac.getBean("proTest");
proTest.test();
}
常用注解示例-模拟用户登录
配置自动扫描的xml文件
自定义扫描范围
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 设置自动化扫描范围-->
<context:component-scan base-package="com.svt"></context:component-scan>
</beans>
实体类User
先写一个实体类,放用户名称和用户密码
package com.svt.entity;
/**
* User实体类
*/
public class User {
private String userName;//用户名称
private String userPwd;//用户密码
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}
dao层
有了实体类就可以在dao层开始编写代码,先定义登陆的账号密码,再通过用户名查询用户对象,如果存在,返回对应的用户对象,如果不存在,返回null
这里用了注解@Repository
package com.svt.dao;
import com.svt.entity.User;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
//定义登陆的账号密码
private final String USERNAME="admin";
private final String USERPWD="admin";
/**
* 通过用户名查询用户对象
* 如果存在,返回对应的用户对象,如果不存在,返回null
* @param userName
* @return
*/
public User queryUserByUserName(String userName){
User user=null;
//判断用户名是否存在
if (!USERNAME.equals(userName)){
return null;
}
//存在
user=new User();
user.setUserName(USERNAME);
user.setUserPwd(USERPWD);
return user;
}
}
消息模型对象MessageModel
return的user需要接受处理,写一个消息模型对象来处理
package com.svt.entity.vo;
/**
* 消息模型对象
* 用来接收处理结果
* resultCode 状态码
* 1=成功 0=失败
* resultMsg 提示信息
*/
public class MessageModel {
private Integer resultCode = 1;//状态码
private String resulyMag;//提示信息
public Integer getResultCode() {
return resultCode;
}
public void setResultCode(Integer resultCode) {
this.resultCode = resultCode;
}
public String getResulyMag() {
return resulyMag;
}
public void setResulyMag(String resulyMag) {
this.resulyMag = resulyMag;
}
}
service层
service层注入dao层的userDao,验证登陆是否成功
这里用了注解@Service
,@Resource
package com.svt.service;
import com.svt.dao.UserDao;
import com.svt.entity.User;
import com.svt.entity.vo.MessageModel;
import com.svt.util.StringUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class UserService {
@Resource
private UserDao userDao;
/**
* 验证登陆是否成功
* 1. 参数的非空校验
* 2. 通过用户名查询用户对象(调用Dao 层的查询方法)
* 3.判断密码是否正确
* @param uname
* @param upwd
* @return
*/
public MessageModel checkUserLogin(String uname,String upwd){
//返回消息模型
MessageModel messageModel = new MessageModel();
//1. 参数的非空校验
if (StringUtil.isEmpty(uname) || StringUtil.isEmpty(upwd)){
//用户名或密码不能为空
messageModel.setResultCode(0);
messageModel.setResulyMag("用户名或密码不能为空");
return messageModel;
}
//2. 通过用户名查询用户对象(调用Dao 层的查询方法)
User user = userDao.queryUserByUserName(uname);
//判断用户对象是否为空
if (user==null){
messageModel.setResultCode(0);
messageModel.setResulyMag("用户名不存在!");
return messageModel;
}
//3.判断密码是否正确
if (!upwd.equals(user.getUserPwd())){
messageModel.setResultCode(0);
messageModel.setResulyMag("用户密码不正确!");
return messageModel;
}
//登陆成功
messageModel.setResulyMag("登陆成功!");
return messageModel;
}
}
其中非空校验用了一个工具类StringUtil
package com.svt.util;
/**
* 字符串工具类
*/
public class StringUtil {
/**
* 判断字符串是否为空
* 为空返回true
* 不为空返回false
* @param str
* @return
*/
public static boolean isEmpty(String str){
if (str==null || "".equals(str.trim())){
return true;
}
return false;
}
}
controller层
判断好了用UserController来接收这个对象
这里用了注解@Controller
,@Autowired
package com.svt.controller;
import com.svt.entity.vo.MessageModel;
import com.svt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
@Autowired
private UserService userService;
public MessageModel userLogin(String uname,String upwd){
MessageModel messageModel=userService.checkUserLogin(uname,upwd);
return messageModel;
}
}
测试Test
一切准备就绪就在UserTest内进行测试
package com.svt.test;
import com.svt.controller.UserController;
import com.svt.entity.vo.MessageModel;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserTest {
public static void main(String[] args) {
//获取spring的上下文环境
BeanFactory factory=new ClassPathXmlApplicationContext("spring.xml");
//得到实例化的userController
UserController userController= (UserController) factory.getBean("userController");
MessageModel messageModel=userController.userLogin("admin","admin");
System.out.println("状态码:"+messageModel.getResultCode()+",提示信息:"+messageModel.getResulyMag());
}
}
不同的用户登录会呈现不同的提示信息
第一种:用户密码不正确!
MessageModel messageModel=userController.userLogin("admin","111");
第二种:用户名或密码不能为空
MessageModel messageModel=userController.userLogin("","");
第三种:用户名不存在!
MessageModel messageModel=userController.userLogin("11","11");
第四种:登陆成功!
MessageModel messageModel=userController.userLogin("admin","admin");