当前位置: 首页 > wzjs >正文

账号权重查询入口站长工具建设公关型的企业网站有哪些

账号权重查询入口站长工具,建设公关型的企业网站有哪些,用discuz怎样做网站,深圳个人网站建设通过前一篇文章,我们已经知道了Spring IoC和DI的基本概念,这篇文章我们将系统地学习Spring-IoC和DI的操作。前面我们提到的IoC控制反转,就是将对象的控制权交给Spring的IoC容器,由IoC容器创建及管理对象。也就是bean(S…

通过前一篇文章,我们已经知道了Spring IoC和DI的基本概念,这篇文章我们将系统地学习Spring-IoC和DI的操作。

前面我们提到的IoC控制反转,就是将对象的控制权交给Spring的IoC容器,由IoC容器创建及管理对象。也就是bean(Spring管理的对象统称为“bean”)的存储。

IoC详解

Bean的存储

将对象存储在Spring中共有两种注解类型可以实现:

1、类注解:@Controller、@Service、@Repository、@Component、@Configuration

2、方法注解:@Bean

@Controller(控制器存储)

如图,在启动类中创建一个子目录Controller:

类中代码如下:

@Controller
public class HelloController {public void sayHi(){System.out.println("hello Controller……");}
}

如何知道当前对象已经存在Spring容器中了呢?

接下来我们学习如何从Spring容器中获取对象。

点进Spring的启动类中,添加上如下代码:

@SpringBootApplication
public class SpringIoCApplication {public static void main(String[] args) {//获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);//从Spring上下文中获取对象HelloController bean = run.getBean(HelloController.class);//使用对象bean.sayHi();}}

观察运行结果,发现成功获取到了Controller对象,并执行了sayHi()方法:把@Controller删去重新执行一遍代码:

将错误信息翻译一下:Spring容器中没有找到这个Bean。

获取Bean的其他方式

上述代码是根据类型来查找对象,如果Spring容器中,同一类型存在多个bean的话,怎么来获取呢?

ApplicationContext也提供了其他获取bean的方式,ApplicationContext获取bean对象的功能,是父类BeanFactory提供的功能。

观察getBean方法的源码:

常用的是上述1,2,4种,这三种方式,获取到的bean是一样的(单例模式)。

其中1,2种都涉及到根据名称来获取对象。bean的名称是什么呢? 

刚才我们讲了bean是spring框架在运行时管理的对象,Spring会给管理的对象起一个名字,就是bean的名称,bean的名称在Spring中是唯一的,类似于学生的学号或者人的身份证号。

Bean的命名约定

默认情况下,首字母小写的驼峰表示(如:我们刚才写的HelloController,Bean的名称为:helloController)。特殊情况下,如果前两个字母均为大写,Bean的名称就是原来的类名(如:UController,Bean的名称是UController)。 


根据这个命名规则,我们来获取Bean:

    //获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);//根据Bean的名称获取BeanHelloController helloController = (HelloController) run.getBean("helloController");//根据Bean的名称和类型获取BeanHelloController bean = run.getBean("helloController", HelloController.class);//根据Bean的类型获取BeanHelloController bean1 = run.getBean(HelloController.class);System.out.println(helloController);System.out.println(bean1);System.out.println(bean);

运行结果:

地址一样,说明对象是同一个。

常见面试题:ApplicationContext VS BeanFactory 

1、关系上,他们是父子关系,BeanFactory的功能ApplicationContext都有。除此之外,ApplicationContext还具备环境、资源管理等功能。

2、性能上

Beanfactory是懒加载(什么时候使用什么时候加载),ApplicationContext是提前加载(一开始就把全部对象加载完了)。

@Service(服务存储)

Service类代码:

@Service
public class UserService {public void sayHi(){System.out.println("hello service");}
}

获取Bean的代码 

    //获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);UserService bean = run.getBean(UserService.class);bean.sayHi();

运行结果: 

 @Repository(仓库存储)

Repository类:

@Repository
public class UserRepository {public void sayHi(){System.out.println("hello Repository");}
}

获取Bean的代码: 

//获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);UserRepository bean = run.getBean(UserRepository.class);bean.sayHi();

运行结果:

@Component(组件存储)

Component类:

@Component
public class UserComponent {public void sayHi(){System.out.println("hello Component");}
}

获取Bean: 

    //获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);UserComponent bean = run.getBean(UserComponent.class);bean.sayHi();

运行结果:

 @Configuration(配置存储)

Configuration类:

@Configuration
public class UserConfig {public void sayHi(){System.out.println("hello configuration");}
}

获取Bean :

 //获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);UserConfig bean = run.getBean(UserConfig.class);bean.sayHi();

运行结果:

为什么要有那么多的类注解?

这与我们前面提到的应用分层是呼应的。让程序员看到类注解之后,就能直接了解当前类的用途。

@Controller:控制层,接收请求,对请求进行处理,并进行响应。

@Service:业务逻辑层,处理具体的业务逻辑。

@Reposity:数据访问层,也称为持久层,负责数据访问操作。

@Configuration:配置层,处理项目中的一些配置信息。

调用流程如下:

查看这些注解的源码: 可以发现它们里面都有一个相同的@Component(元注解)注解,说明它们都是@Component的“子类”。

“@Controller”,@Service和@Repository用于更具体的用例(分别在控制层,业务逻辑层,持久化层)。

方法注解@Bean

类注解是添加到某个类上的,但是存在两个问题:

1、使用外部包里的类,没办法添加类注解。

2、一个类需要多个对象比如多个数据源。

这种情况我们就需要使用方法注解@Bean。

我们先来看看方法注解如何使用:

先创建一个外部包类UserInfo:

@Data
public class UserInfo {private String name;private Integer age;private Integer id;public UserInfo(){}public UserInfo(String name) {this.name = name;}
}

 使用@Bean注解:

public class BeanConfig {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}
}

获取Bean:

   ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);UserInfo bean = run.getBean(UserInfo.class);System.out.println(bean)

将代码写入后发现执行结果如下 :

找不到Bean,这是为什么呢?

在Spring框架的涉及中,方法注解@Bean要配合类注解才能将对象正常存储到Spring容器中。

修改代码如下: 

@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}
}

定义多个对象

对于同一个类如何定义多个对象呢?

修改@Bean类如下:

@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi");}@Beanpublic UserInfo userInfo2(){return new UserInfo("wangwu");}
}

如果我们此时通过类型获取对象,获取的是哪个对象呢? 

//获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);UserInfo bean = run.getBean(UserInfo.class);System.out.println(bean);

运行结果:报错信息显示:期望只有一个匹配,但是根据这个类型找到了3个Bean,userInfo,userInfo1,userInfo2。

接下来我们可以通过Bean的名称来获取Bean,我们刚才讲了类注解的Bean的名称,那方法注解Bean的名称又是什么呢?

其实就是——方法名。

代码如下:

         //获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);UserInfo bean = (UserInfo) run.getBean("userInfo");System.out.println(bean);UserInfo bean1 = (UserInfo) run.getBean("userInfo1");System.out.println(bean1);UserInfo bean2 = (UserInfo) run.getBean("userInfo2");System.out.println(bean2);

运行结果:

Bean的名称总结 

1、五大注解:

类名:首字母小写

        如果类名前两位为大写,bean的名称为类名本身

2、@Bean

bean 名称:方法名

扫描路径

使用前面学习的注解声明的bean,一定会生效吗?

不一定(原因:bean想要生效,还需要被Spring扫描)

将启动类放到Controller目录下: 写上如下代码:

   //获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);HelloController bean1 = run.getBean(HelloController.class);bean1.sayHi();UserService bean = run.getBean(UserService.class);bean.sayHi();

运行结果:可以看到HelloController的bean对象能够正常获取并使用,而UserService的bean对象却显示没有找到。

这是为什么呢?

Spring的默认扫描路径是当前目录和当前目录下的子目录。我们可以通过@ComponentScan来配置扫描路径。

修改代码如下:

@ComponentScan("com.example.springioc")
@SpringBootApplication
public class SpringIoCApplication {public static void main(String[] args) {//获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);HelloController bean1 = run.getBean(HelloController.class);bean1.sayHi();UserService bean = run.getBean(UserService.class);bean.sayHi();}
}

运行结果:

推荐做法:

把启动类放在我们希望扫描的包的路径下,这样我们定义的bean就都可以被扫描到。

DI详解

上面我们讲解了控制反转IoC的细节,接下来,我们学习依赖注入DI的细节。

依赖注入是一个过程,是指IoC容器在创建Bean时,去提供运行时所依赖的资源,而资源指的就是对象。

关于依赖注入,Spring也给我们提供了三种方式:

1、属性注入

2、构造方法注入

3、Setter注入

属性注入

属性注入需要使用@Autowired这个注解。

例如:在HelloController类中注入UserSeverice对象。

HelloController类代码如下:

@Controller
public class HelloController {@Autowiredprivate UserService userService;public void sayHi(){userService.sayHi();System.out.println("hello Controller……");}
}

 获取Bean并调用sayHi方法:

//获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);HelloController bean1 = run.getBean(HelloController.class);bean1.sayHi()

执行结果:

去掉 @Autowired,重新执行:

出现空指针异常。

构造方法注入 

HelloController代码:


@Controller
public class HelloController {private UserService userService;public HelloController(UserService userService) {this.userService = userService;}public void sayHi(){userService.sayHi();System.out.println("hello Controller……");}
}

获取使用Bean代码 :

    //获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);HelloController bean1 = run.getBean(HelloController.class);bean1.sayHi()

执行结果: 那如果我给HelloController再加上一个无参构造方法呢?

代码修改如下:

@Controller
public class HelloController {private UserService userService;public HelloController() {}public HelloController(UserService userService) {this.userService = userService;}public void sayHi(){userService.sayHi();System.out.println("hello Controller……");}
}

可以看到报了一个空指针异常,这是因为Spring会默认使用无参的构造方法,这就导致了userService是一个空对象 。

解决办法:

为构造方法添加@Autowired注解:

@Controller
public class HelloController {private UserService userService;public HelloController() {}
@Autowiredpublic HelloController(UserService userService) {this.userService = userService;}public void sayHi(){userService.sayHi();System.out.println("hello Controller……");}
}

那么如果我注入两个对象,并且加入带一个参数的构造方法和带两个参数的构造方法(不加注解的情况)呢?

代码如下:

@Controller
public class HelloController {private UserService userService;private UserRepository userRepository;public HelloController(UserService userService) {this.userService = userService;}public HelloController(UserService userService, UserRepository userRepository) {this.userService = userService;this.userRepository = userRepository;}public void sayHi(){userRepository.sayHi();userService.sayHi();System.out.println("hello Controller……");}
}

 获取使用Bean:

    //获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);HelloController bean1 = run.getBean(HelloController.class);bean1.sayHi()

执行结果: 

翻译一下这两个错误日志:构造方法有两个,我不知道应该使用哪个构造方法(没有默认构造方法)。

我们为两个参数的构造方法添加上@Autowired注解:

@Controller
public class HelloController {private UserService userService;private UserRepository userRepository;public HelloController(UserService userService) {this.userService = userService;}@Autowiredpublic HelloController(UserService userService, UserRepository userRepository) {this.userService = userService;this.userRepository = userRepository;}public void sayHi(){userRepository.sayHi();userService.sayHi();System.out.println("hello Controller……");}
}

代码成功执行:

总结:

构造函数注入

1、只有一个构造函数的情况,不需要加@Autowired

2、如果有多个构造函数,需要指定默认的构造函数(通过@Autowired指定,如果未指定,默认使用无参的构造函数

构造函数规范

1、如果添加构造函数,把无参构造函数显示添加

依赖注入:

添加构造函数时,使用@Autowired告知Spring要使用的构造函数。 

 Setter方法注入

Setter方法注入和属性注入一样需要添加@Autowired注解,否则会报空指针异常

@Controller
public class HelloController {private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public void sayHi(){userService.sayHi();System.out.println("hello Controller……");}
}

 获取使用Bean:

    //获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);HelloController bean1 = run.getBean(HelloController.class);bean1.sayHi()

执行结果:

三种注入方式优缺点分析(八股文): 

@Autowired存在问题

当同一类型存在多个bean时,使用@Autowired会存在问题。

刚才的Beanconfig类中就存在多个bean:

@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi");}@Beanpublic UserInfo userInfo2(){return new UserInfo("wangwu");}
}

同样将它注入HelloController类中: 

@Controller
public class HelloController {@Autowiredprivate UserInfo userInfo;public void sayHi(){System.out.println(userInfo);System.out.println("hello Controller……");}
}

获取Bean:

    //获取Spring上下文对象ConfigurableApplicationContext run = SpringApplication.run(SpringIoCApplication.class, args);HelloController bean1 = run.getBean(HelloController.class);bean1.sayHi()

可以看到,此时是能正常运行的: 但是倘若我给要注入的对象换个名字:

@Controller
public class HelloController {@Autowiredprivate UserInfo user;public void sayHi(){System.out.println(user);System.out.println("hello Controller……");}
}

执行结果: 

报错原因:非唯一的Bean对象。

如何解决上述问题呢?Spring提供了三种解决方案:

  • @Primary
  • @Qualifier
  • @Resource

使用@Primary注解:当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。

代码如下:

@Configuration
public class BeanConfig {@Primary//指定该Bean未默认Bean的实现@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi");}@Beanpublic UserInfo userInfo2(){return new UserInfo("wangwu");}
}

重新执行 :

使用@Qualifier注解:指定当前要注入的bean对象。在@Qualifier的value属性中,指定注入的bean的名称。(@Qualifiler注解不能单独使用,必须配合@Autowired使用)。

HelloController代码如下:

@Controller
public class HelloController {@Qualifier("userInfo1")@Autowiredprivate UserInfo user;public void sayHi(){System.out.println(user);System.out.println("hello Controller……");}
}

执行结果:

使用@Resource注解:是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

代码如下: 

@Controller
public class HelloController {@Resource(name = "userInfo2")private UserInfo user;public void sayHi(){System.out.println(user);System.out.println("hello Controller……");}
}

结果:

常见面试题:@Autowired VS @Resource的区别

@Autowired是spring框架提供的注释,而@Resource是JDK提供的注释。

@Autowired默认按照类型注入,而@Resource是按照名称注入,相比于@Autowired来说,@Resource支持更多参数设置,例如name设置,根据名称获取Bean

http://www.dtcms.com/wzjs/536766.html

相关文章:

  • 锐奇智能手机网站建设最优惠的网站优化
  • 村级网站建设助力脱贫攻坚传奇世界游戏官网
  • 网站等保测评长春哪家网络公司做网站专业
  • 非凡网站开发培训做推广怎么做
  • 快乐麻花网站源码做爰的视频网站
  • 用vs2015做网站教程静态网页文件
  • 华为荣耀商城官网seo引流赚钱吗
  • 校园网站建设申请报告wordpress mnews主题
  • 做网站一个程序员够吗网站关键字多少个
  • 网站数据库特点济南网站建设seo优化
  • 宣传片素材网站新闻标题标题怎样进行优化
  • 商贸有限公司网站建设推广方案框架
  • 连云港建设厅官方网站做网站电商
  • 做网站构思推销网站建设
  • 饮料企业哪个网站做的比较好自做闪图网站
  • 中国最受欢迎的网站zt16j门户网
  • 网站首页框架图深圳有名的建筑公司
  • 龙岗平湖网站开发兰陵住房建设局网站
  • 网站做多长时间才会成功怎么自己做个网站做链接跳转
  • 国外有没有做物理小实验的网站wordpress响应式主题在哪
  • 广告位网站建设泉州建设网站公司哪家好
  • 做册子模板素材有哪些网站邢台见贤网络科技有限公司
  • 西安北郊网站建设做代理需要交钱吗
  • 网站建设经费的函上海广告投放公司
  • 常州网站建设 个人旅游搜索网站开发
  • 搭建影视网站vi设计公司排行榜
  • 免费模板网站哪个好温州有没有做鞋的网站
  • 德国域名申请网站讯代理网站
  • 南京网站搜索优化开放平台设计方案
  • 微网站的定义wordpress添加自定义字段