栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring更简单存储和更简单取出---使用注解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring更简单存储和更简单取出---使用注解

面试题:三种注入方式的区别:

都要先定义外部类对象,因为你要用到外部类

1)属性注入的优点时简洁,使用方便,但是他的缺点也是很明显的,它只能用于IOC容器,如果是非IOC容器那么是不可用的,况且只有在使用的时候才会出现空指针异常 2)当使用构造器进行注入的时候,如果需要注入的对象比较多,那么咱们的构造方法比较臃肿,这时Spring前期不推荐构造器进行注入的理由,但是后期官方又说,如果出现臃肿的情况,是应该进行考虑一下当前的类是否符合程序的单一职责的设计模式了,在我们进行使用之前,一定要保证使用之前一定能把保证注入的类不为空
 下面的这几个变量都指向了同一个UserService,况且这个Service是单例模式的
 private UserService userService1;
    private UserService userService2;
    private UserService userService3;
  @Autowired
    public UserController(UserService userService1, UserService userService2, UserService userService3) {
        this.userService1 = userService1;
        this.userService2 = userService2;
        this.userService3 = userService3;
    }
3)Setter注解时Spring前期版本推荐的注入方式,但是通用性是不如构造方法的,有多个Service的时候,只需要多写几个构造方法就可以了;
1.更简单进行存储: 1.先进行创建Spring的项目 先进行创建maven项目,在pom.xml里面引入对Spring所依赖的jar包(核心包:5.2.3)
 
        
            org.springframework
            spring-context
            5.2.3.RELEASE
        

        
        
            org.springframework
            spring-beans
            5.2.3.RELEASE
        
2.配置Spring的XML文件:在resouces下面创建一个xml文件,引入下面的这段代码,


    
        
    
1)Spring在一开始启动的时候并不会扫描所有的包,扫描所有的类,只会从base-package这个根路径里面找; 2)配置Spring xml文件的时候,我们要配置Spring组件扫描路径,只有在这个路径里面,被注解修饰过的类(对象)才会被放到Spring里面; 3.创建一个普通类,添加main方法,主要的作用就是方便于我们进行调试----进行测试的一种方式 4.使用注解实现对象存储在Spring框架里面

1)类注解:五大类注解

2)方法注解:@Bean

注意:

1)必须配合类注解进行使用

2)类名首字母和第二个字母都是非大写,那么通过首字母小写的方式来进行获取到bean,如果说首字母和第二个字母都是大写,那么直接使用原Bean名,来进行获取

4.1控制器@Controller来实现对象存储(一定要在APP目录下面)

注意事项:

1)读取存入对象的id:默认情况下是首字母小写

2)关于存储目录:所有需要存储到Spring框架中的对象的目录,必须在Spring配置文件(XML)文件配置的目录下

存入到Spring里面的内容是一个键值对:Key值是被注解修饰过的类名的首字母的小写形式,Value就是类名

package APP.Service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void start(String name){
        System.out.println("我是Service");
    }
}

import APP.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloServlet {
    public static void main(String[] args) {
        //1先获取Spring的上下文对象
        ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");
        //2从Spring获得存入的对象,getBean里面的参数之前写的是xml中配置id属性的值,这里面的参数必须是存入类的首字母的小写,和类对象
       UserController userController=(UserController) context.getBean("userController",UserController.class);
       //3使用对象
        userController.start("hhh");
    }
}

这种使用注解来进行存储对象的方式和上节使用注册bean的方式是可以进行混用的

4.2使用Service注解注册类
  //1先获取Spring的上下文对象
        ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");
        //2从Spring获得存入的对象,getBean里面的参数之前写的是xml中配置id属性的值,这里面的参数必须是存入类的首字母的小写,和类对象
       UserService service=(UserService)context.getBean("userService", UserService.class);
       //3使用对象
        service.start("hhh");

package APP.Service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void start(String name){
        System.out.println("我是Service"+name);
    }
}
4.3使用@Repostory来进行注册类
  package APP.Repostory;

import org.springframework.stereotype.Repository;

@Repository
public class UserRepostory {
    public void start(String name)
    {
        System.out.println("UserRepostory");
    }
}
ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");
        UserRepostory userRepostory=context.getBean("userRepostory",UserRepostory.class);
        userRepostory.start("hhhh");
 4.4使用@Configuration来进行注册类
@Configuration
public class UserConfigrithon {
    public void start()
    {
        System.out.println(1);
    }
}
 ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");
        UserConfigrithon userConfigrithon=context.getBean("userConfigrithon", UserConfigrithon.class);
        userConfigrithon.start();
4.5使用@UserComponent注解的方式来进行注册类的
@Component
public class UserComponent {
    public void run()
    {
        System.out.println("hhlll");
    }

 ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");
        UserComponent userComponent=context.getBean("userComponent",UserComponent.class);
        userComponent.run();
4.6使用方法注解:@Bean将对象存入到Spring里面

注意事项:Spring默认情况下是类扫描,默认是类注解而不是方法注解,因此如果使用的是方法注解@Bean,那么就必须要配合类注解进行使用,这个类注解可以是任意一个,通常情况下就是搭配@Component组件和Bean一块进行使用才可以将方法返回对象存储到Spring里面

我们在APP包里面进行创建两个类,User类和GetBean类,在GetBean类里面有一个方法返回User

package APP.BeanMethod;

public class User {
    public int id;
    public String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + ''' +
                '}';
    }
}


package APP.BeanMethod;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class GetBean {
    @Bean//将当前对象存储到Spring里面
    public User GetUser(){
        User user=new User();
        user.setId(1);
        user.setName("李佳伟");
        return user;
    }
}


  ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");
   User user=context.getBean("GetUser",User.class);
//第一个参数表示的是方法名,第二个参数表示的是要存入的类对象
   System.out.println(user);

进行上面演示的时候的Java目录:

@Bean的重命名

  
@Component
public class GetBean {
    @Bean(name ="u1")//将当前User对象存储到Spring里面
    public User GetUser(){
        User user=new User();
        user.setId(1);
        user.setName("李佳伟");
        return user;
    }
}
//这时候可以进行不关注方法名
ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");
   User user=context.getBean("u1",User.class);
   System.out.println(user);
但是我们写了@Bean(name = "u1")之后,写这个方法就会发生报错
   User user=context.getBean("user",User.class)

@Bean重命名可以有多个别名,但是当指定别名之后,使用方法名我们就去不到对应的对象了

1)@Controller是一个组合注解,从业务逻辑来说,我们可以认为Controller是Component的一个子类 

2)这些注解全部是Component的子类

有这么多注解是为了成需要更方便的看代码的,是为了让程序员知道这些类是干什么的;

3)对于方法名/类名来说,方法名字符大于2个,并且前两个字符都是大写,那么使用原来的类名作为Bean的名字;大驼峰命名规则,那么就将首字母小写;

2从Spring中获取对象的手段 1)属性注入(属性注册),比如说我要在UserController里面调用UserService的方法,我们最早的方法是创建一个UserService对象(缺点是底层的类发生改变,整个想上调用链的类都要发生改变)

我们为了进行验证属性注入的方式,做了以下几个工作:

1)先在UserService里面写了一个方法,根据不同的用户ID向数据库中查询用户并返回;

 public User run(Integer id) {//前端传过来的参数可能是空,根据用户ID查询数据库;
        if (id == 1) {
            User user = new User();
            user.setId(id);
            user.setName("周韵杠");
            return user;
        }else{
            User user=new User();
            user.setName("胡子");
            user.setId(id);
            return user;
        }
    }
2)我们再从UserController中写一段代码,先获取到UserService对象,在调用UserService里面的方法获取到User对象
package APP.Controller;

import APP.BeanMethod.User;
import APP.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
//将当前的类注册到Spring里面
@Controller
public class UserController {
    public void start( String name)
    {
        System.out.println("当前的类已经启动,我是被Contraller注解修饰的"+name);
    }
//1.属性注入,属性注册,从Spring里面进行获取一个对象,并注册到当前类,在属性上加上注解
    @Autowired
    private UserService userService;
    public User findUser(Integer id){
        if(id==null)
        {
            return null;
        }
        User user=userService.run(id);
        return user;
    }
}
3)我们在main方法里面先获取到UserController对象,在调用里面的方法,通过层层调用,获取到UserController对象
 //1.先进行获取Spring的上下文对象
    ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");
  //2.得到Controller对象
    UserController userController=context.getBean("userController",UserController.class);
    //调用findUser方法进行查询用户,实际上的查询是在UserService里面进行查询的
    User user=userController.findUser(1);
     System.out.println(user);

2)Setter注入
//1将UserService注册到当前类里面(使用Setter注入的方式),首先先进行创建一个属性,定义一个属性
private UserService userService;
//2.给这个属性设置一个Setter方法,并给Setter方法加上一个@Autowired的注解
@Autowired//如果说缺少了这个注解就会发生空指针异常
public void setUserService(UserService userService) {
    this.userService = userService;
}
//3新创建一个方法,在方法里面调用UserService的查询方法,并返回用户对象
 public User FindUser(Integer id) { 
    if(id==null) {
     return null; 
          }
    else{
       User user= userService.run(id);
       return user;
     }
}
再Setter注入里面需要进行注意:在Setter方法上面是不可以省略@Autowried,否则就会注入失败
3)通过构造方法来进行注入 
//1.使用构造方法来进行注入对象,并先进行创建一个要注入的对象
  private UserService userService;
//2创建构造方法,给构造方法上面添加@Autowired注解
  @Autowired
  public UserController(UserService userService) {
      this.userService = userService;
  }
//3调用Service方法来返回User对象
public User FindUser(Integer id) {
    if(id==null) {
        return null;}
else{
        User user= userService.run(id);
        return user;
    }
}
注意事项:如果说当前类的里面只有一个构造方法,那么@Autowired注解是可以被省略的,当有多个构造方法构成重载时,那么是不可以进行省略的;
上面我们都是通过@Autowired这个注解来实现注入的,下面我们类似使用@resource来实现对象的注入,它的用法是和@Autowired的用法是相同的;
1)这样写也是可以的,通过属性注入的方式是可以取出对象的
@Controller
public class UserController4 {
    @Resource
    private UserService userService;
    public User Start(Integer ID)
    {
        if(ID==null||ID.equals(""))
        {
            return null;
        }else{
            User user= userService.run(1);
            return user;
        }
    }
2)我们也是可以通过Setter的方式来进行构建的
  ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");
        UserController4 userController4=context.getBean("userController4",UserController4.class);
        User user=userController4.FindById(2);
        System.out.println(user);

@Controller
public class UserController4{
    @Resource
    private UserService userService;

    public UserController4(UserService userService) {
        this.userService = userService;
    }
    public User FindById(Integer id)
    {
        if(id==null||id.equals(""))
        {
            return null;
        }else{
            User user= userService.run(id);
            return user;
        }
    }
}
@Autowired和@Resource有什么区别? 1)@Resource是来源于JDK,但是@Autowired是来源于Spring框架的的· 2)针对作用范围来说:我们通过不断的测试可以得知,我们使用resource注解的方式只能通过属性注入和Setter注入的方式来进行获取对象,但是如果使用构造器的方式就会发生报错,但是@Autowired可以进行属性注入,Setter注入,构造器注入; 3)功能不同,@Resource本身可以配置更多的属性进行使用,但是@Autowired支持的属性比较少;比如说@Resource可以配合name属性来进行使用,从而完成对象的别名注入 4)这两个注解进行使用的时候,他们先会尝试根据名字进行获取,这种方式如果获取不到,然后再根据.class的方式进行获取;

context.getBean(UserController.class);

context.getBean("userController");

如果注入的名称是不存在的,并且类型有多个那么注入就会失败

@Component
public class GetBean {
    @Bean(name="u1")//将当前User对象存储到Spring里面
    public User GetUser1(){
        User user=new User();
        user.setId(1);
        user.setName("李佳伟");
        return user;
    }
    @Bean(name="u2")
    public User GetUser2(){
        User user=new User();
        user.setName("张某某");
        user.setId(2);
        return user;
    }
}

@Controller
public class Controller1 {
    @Autowired
    private User user;
    public User getUser()
    {
        return user;
    }
}
  ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");
       Controller1 userController=context.getBean("controller1", Controller1.class);
       User user= userController.getUser();
        System.out.println(user);
上面的这种写法是错误的,因为我们在使用属性注入的时候写了一句代码private User user(上面写了一个注解)----我们的注解会先拿着user名字到User那边的对象去找(本质上是去找name属性,看看是不是和u1,u2是相等的,显然是不相等的,名字都不相等了,然后对象还具有多个,那么就会发生报错)

下面这几种写法是对的:

package APP.BeanMethod;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class GetBean {
    @Bean//将当前User对象存储到Spring里面
    public User GetUser1(){
        User user=new User();
        user.setId(1);
        user.setName("李佳伟");
        return user;
    }
    @Bean
    public User GetUser2(){
        User user=new User();
        user.setName("张某某");
        user.setId(2);
        return user;
    }
}

@Controller
public class Controller1 {
    @Autowired
    private User GetUser1;//这里面的变量名必须和上面的方法名是相同的
    public User getUser()
    {
        return GetUser1;
    }
}
下面的main方法代码是不变的
@Controller
public class Controller1 {
    @Autowired
    private User u2;
    public User getUser()
    {
        return u2;
    }
}


@Component
public class GetBean {
    @Bean(name ="u1")//将当前User对象存储到Spring里面
    public User GetUser1(){
        User user=new User();
        user.setId(1);
        user.setName("李佳伟");
        return user;
    }
    @Bean(name="u2")
    public User GetUser2(){
        User user=new User();
        user.setName("张某某");
        user.setId(2);
        return user;
    }
}

总结:private要么和方法名字是相同的,要么和bean中的name属性有一个相同

除了这两种方法之外还有两种解决方案:

解决相同类型的多个Bean的报错

1)@Resource(name = "指定Bean的名称")

@Component
public class GetBean {
    @Bean(name ="u1")//将当前User对象存储到Spring里面
    public User GetUser1(){
        User user=new User();
        user.setId(1);
        user.setName("李佳伟");
        return user;
    }
    @Bean(name="u2")
    public User GetUser2(){
        User user=new User();
        user.setName("张某某");
        user.setId(2);
        return user;
    }
}

@Controller
public class Controller1 {
    @Resource(name ="u1")
    private User user;
    public User getUser()
    {
        return user;
    }
}

2)使用注入注解@Qualifier来进行搭配使用

@Component
public class GetBean {
    @Bean(name ="u1")//将当前User对象存储到Spring里面
    public User GetUser1(){
        User user=new User();
        user.setId(1);
        user.setName("李佳伟");
        return user;
    }
    @Bean(name="u2")
    public User GetUser2(){
        User user=new User();
        user.setName("张某某");
        user.setId(2);
        return user;
    }
}

@Controller
public class Controller1 {
  @Autowired
  @Qualifier(value = "u1")
    private User user;
    public User getUser()
    {
        return user;
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1013174.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号