Go最新IOC DI配置管理第三方bean及注解开发。_idea 中bean怎么配置,百度Golang岗一面+二面内容

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

4、注解开发依赖注入

三、IOC/DI注解开发管理第三方bean

1、注解开发管理第三方bean

2、注解开发实现为第三方bean注入资源


一、IOC/DI 配置管理第三方bean

1、配置第三方bean

▶ 实现Druid管理

▷ 步骤1 : 导入druid的依赖

pom.xml中添加依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>

▷ 步骤2 : 配置第三方bean

在applicationContext.xml配置文件中添加DruidDataSource的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--管理DruidDataSource对象-->
    <bean class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

</beans>

▷ 步骤3 : 从IOC容器中获取对应的bean对象

public class App {
    public static void main(String[] args) {
       ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
       DataSource dataSource = (DataSource) ctx.getBean("dataSource");
       System.out.println(dataSource);
    }
}

▶ 实现C3P0管理

▷ 步骤1 : 导入C3P0的依赖

pom.xml中添加依赖

<dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

▷ 步骤2 : 配置第三方bean

在applicationContext.xml配置文件中添加配置

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_db"/>
    <property name="user" value="root"/>
    <property name="password" value="root"/>
    <property name="maxPoolSize" value="1000"/>
</bean>

注意:

● ComboPooledDataSource的属性是通过setter方式进行注入
 ● 想注入属性就需要在ComboPooledDataSource类或其上层类中有提供属性对应的setter方法
 ● C3P0的四个属性和Druid的四个属性是不一样的

▷ 注意:

● 数据连接池在配置属性的时候,除了可以注入数据库连接四要素外还可以配置很多其他的属性,具体都有哪些属性用到的时候再去查,一般配置基础的四个,其他都有自己的默认值
 ● Druid 和 C3P0在没有导入mysql驱动包的前提下,Druid不会报错,C3P0会报错,说明Druid在初始化的时候没有去加载驱动,而C3P0刚好相反
 ● Druid程序运行虽然没有报错,但是当调用DruidDataSource的getConnection()方法获取连接的时候,也会报找不到驱动类的错误。

2、加载properties 文件

▶ 第三方bean属性化

▷ 步骤1 : 准备properties配置文件

resources下创建一个jdbc.properties文件,并添加对应的属性键值对

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
jdbc.username=root
jdbc.password=root

▷ 步骤2 : 开启context命名空间

在applicationContext.xml中开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>

▷ 步骤3 : 加载properties配置文件

在配置文件中使用context命名空间下的标签来加载properties配置文件

<context:property-placeholder location="jdbc.properties"/>

▷ 步骤4 : 完成属性注入

使用${key}来读取properties配置文件中的内容并完成属性注入

<?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">
    
    <context:property-placeholder location="jdbc.properties"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

▶ 读取单个属性

▷ 步骤1 : 在项目中添对应的类

BookDao和BookDaoImpl类,并在BookDaoImpl类中添加name属性与setter方法

public interface BookDao {
    public void save();
}

public class BookDaoImpl implements BookDao {
    private String name;

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

    public void save() {
        System.out.println("book dao save ..." + name);
    }
}

▷ 步骤2 : 完成配置文件的读取与注入

在applicationContext.xml添加配置,bean的配置管理读取外部properties依赖注入:

<?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">
    
    <context:property-placeholder location="jdbc.properties"/>
    
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        <property name="name" value="${jdbc.driver}"/>
    </bean>
</beans>

▶ 注意事项

▷ 问题一 : 键值对的key为username引发的问题

1.在properties中配置键值对的时候,如果key设置为username

 username=root666

2.在applicationContext.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: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">
      
      <context:property-placeholder location="jdbc.properties"/>
      
      <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
          <property name="name" value="${username}"/>
      </bean>
  </beans>

3.运行后,在控制台打印的却不是root666,而是自己电脑的用户名。出现问题的原因是<context:property-placeholder/> 标签会加载系统的环境变量,而且环境变量的值会被优先加载。运行下面的代码查看系统的环境变量:

  public static void main(String[] args) throws Exception{
      Map<String, String> env = System.getenv();
      System.out.println(env);
  }

解决方案

<context:property-placeholder location="jdbc.properties" 
    system-properties-mode="NEVER"/>

system-properties-mode: 设置为NEVER,表示不加载系统属性,就可以解决上述问题。

还有一个解决方案就是避免使用username作为属性的key

▷ 问题二 : 当有多个properties配置文件需要被加载,该如何配置?

1.调整下配置文件的内容,在resources下添加jdbc.properties,jdbc2.properties,内容如下:

jdbc.properties

  jdbc.driver=com.mysql.jdbc.Driver
  jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
  jdbc.username=root
  jdbc.password=root

jdbc2.properties

username=root666

2.修改applicationContext.xml

<!--方式一 -->
<context:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER"/>

● 方式一 : 可以实现,如果配置文件多的话,每个都需要配置

<!--方式二-->
<context:property-placeholder location="*.properties" system-properties-mode="NEVER"/>

● 方式二 : \*.properties 代表所有以properties结尾的文件都会被加载,可以解决方式一的问题,但是不标准

<!--方式三 -->
<context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/>

● 方式三 : 标准的写法,classpath:代表的是从根路径下开始查找,但是只能查询当前项目的根路径

<!--方式四-->
<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>

● 方式四 : 不仅可以加载当前项目还可以加载当前项目所依赖的所有项目的根路径下的properties配置文件

▶ 小结

● 开启context命名空间:

● 加载properties配置文件:

<context:property-placeholder location="" system-properties-mode="NEVER"/>

● 在applicationContext.xml引入properties配置文件中的值:

${key}

3、核心容器

▶ 容器的创建方式

▷ 类路径下的XML配置文件:直接加载类路径下的文件

ApplicationContext ctx = 
    new ClassPathXmlApplicationContext("applicationContext.xml");

▷ 文件系统下的XML配置文件:需要写完整的系统路径

ApplicationContext ctx = 
    new FileSystemXmlApplicationContext("
        D:\\workspace\\spring\\spring_10_container\\
        src\\main\\resources\\applicationContext.xml"); 

▶ bean 获取的三种方式

▷ 方式一 :这种方式存在的问题是每次获取的时候都需要进行类型转换

BookDao bookDao = (BookDao) ctx.getBean("bookDao");

▷ 方式二:这种方式可以解决类型强转问题,但是参数又多加了一个。

BookDao bookDao = ctx.getBean("bookDao",BookDao.class);

▷ 方式三 : 这种方式就类似依赖注入中的按类型注入。必须要确保IOC容器中该类型对应的bean对象只能有一个。

BookDao bookDao = ctx.getBean(BookDao.class);

▶ 容器类层次结构

(1)在IDEA中双击shift,输入BeanFactory

(2)点击进入BeanFactory类,ctrl+h,就能查看到如下结构的层次关系

▶ BeanFactory的使用

▷ 使用BeanFactory来创建IOC容器的具体实现方式为:

public class AppForBeanFactory {
    public static void main(String[] args) {
        Resource resources = new ClassPathResource("applicationContext.xml");
        BeanFactory bf = new XmlBeanFactory(resources);
        BookDao bookDao = bf.getBean(BookDao.class);
        bookDao.save();
    }
}

▷ 对比

● BeanFactory是延迟加载,只有在获取bean对象的时候才会去创建

● ApplicationContext是立即加载,容器加载的时候就会创建bean对象

● ApplicationContext要想成为延迟加载,只需要按照如下方式进行配置:(加上 lazy-init)

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"  
    lazy-init="true"/>

▶ 总结

▷ 容器相关

● BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
 ● ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载
 ● ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能
 ● ApplicationContext接口常用初始化类
  ○  ClassPathXmlApplicationContext(常用) 
  ○ FileSystemXmlApplicationContext

▷ bean相关

▷ 依赖注入相关

二、注解开发

1、注解开发定义bean

▶ 实现步骤

▷ 步骤1 : 删除原XML配置

将配置文件中的<bean>标签删除掉

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

▷ 步骤2 : Dao上添加注解

在BookDaoImpl类上添加@Component注解

@Component("bookDao")
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ..." );
    }
}

● 注意 : @Component注解不可以添加在接口上,因为接口是无法创建对象的。

● XML与注解配置的对应关系:

▷ 步骤3 : 配置Spring的注解包扫描

为了让Spring框架能够扫描到写在类上的注解,需要在配置文件上进行包扫描

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <context:component-scan base-package="com.itheima"/>

</beans>

● 注意:

1、component-scan:

○ component : 组件,Spring将管理的bean视作自己的一个组件
  ○ scan:扫描

2、base-package指定Spring框架扫描的包路径,它会扫描指定包及其子包中的所有类上的注解。

○ 包路径越多[如:com.itheima.dao.impl],扫描的范围越小速度越快
  ○ 包路径越少[如:com.itheima],扫描的范围越大速度越慢
  ○ 一般扫描到项目的组织名称即Maven的groupId下[如:com.itheima]即可。

▷ 步骤4 : Service上添加注解

在BookServiceImpl类上也添加@Component交给Spring框架管理

@Component
public class BookServiceImpl implements BookService {
   
}

▷ 步骤5 : 运行程序

在App类中,从IOC容器中获取BookServiceImpl对应的bean对象,打印

public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //按名称
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        System.out.println(bookDao);
        //按类型获取bean
        BookService bookService = ctx.getBean(BookService.class);
        System.out.println(bookService);
    }
}

说明 :

● BookServiceImpl类没有起名称,所以在App中是按照类型来获取bean对象

● @Component注解如果不起名称,会有一个默认值就是当前类名首字母小写,所以也可以按照名称获取,如:

BookService bookService = (BookService)ctx.getBean("bookServiceImpl");
System.out.println(bookService);

● 对于@Component注解,还衍生出了其他三个注解@Controller@Service@Repository

通过查看源码会发现:(这三个注解和@Component注解的作用是一样的,为什么要衍生出这三个呢?为了方便我们后期在编写类的时候能很好的区分出这个类是属于表现层业务层还是数据层的类。)

● @Component

2、纯注解开发模式

▶ 实现方式

首先将配置文件applicationContext.xml删除掉,使用类来替换。

▷ 步骤1 : 创建配置类

创建一个配置类SpringConfig

public class SpringConfig {
}

▷ 步骤2 : 标识该类为配置类

在配置类上添加@Configuration注解,将其标识为一个配置类,替applicationContext.xml

@Configuration
public class SpringConfig {
}

▷ 步骤3 : 用注解替换包扫描配置

在配置类上添加包扫描注解@ComponentScan替换<context:component-scan base-package=""/>

@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}

▷ 步骤4 : 创建运行类并执行

创建一个新的运行类AppForAnnotation

public class AppForAnnotation {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        System.out.println(bookDao);

        BookService bookService = ctx.getBean(BookService.class);
        System.out.println(bookService);
    }
}

运行AppForAnnotation,可以看到两个对象依然被获取成功。

▶ 小总结

● Java类替换Spring核心配置文件

● @Configuration注解用于设定当前类为配置类

● @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式

 @ComponentScan({com.itheima.service","com.itheima.dao"})

● 读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象

//加载配置文件初始化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

//加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

● @Configuration

● @ComponentScan

3、注解开发bean作用范围与生命周期管理

▶ @Scope 注解

默认情况下bean是单例,要想变成非单例,只需要在其类上添加@scope注解,列如:

@Repository
//@Scope设置bean的作用范围
@Scope("prototype")
public class BookDaoImpl implements BookDao {

    public void save() {
        System.out.println("book dao save ...");
    }
}

▶ Bean的生命周期

● @PostConstruct

● @PreDestroy

● 注意 : @PostConstruct和@PreDestroy注解如果找不到,需要导入下面的jar包。找不到的原因是,从JDK9以后jdk中的javax.annotation包被移除了,这两个注解刚好就在这个包中。

<dependency>
  <groupId>javax.annotation</groupId>
  <artifactId>javax.annotation-api</artifactId>
  <version>1.3.2</version>
</dependency>

例如:

@Repository
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
    @PostConstruct //在构造方法之后执行,替换 init-method
    public void init() {
        System.out.println("init ...");
    }

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

● 注意 : @PostConstruct和@PreDestroy注解如果找不到,需要导入下面的jar包。找不到的原因是,从JDK9以后jdk中的javax.annotation包被移除了,这两个注解刚好就在这个包中。

<dependency>
  <groupId>javax.annotation</groupId>
  <artifactId>javax.annotation-api</artifactId>
  <version>1.3.2</version>
</dependency>

例如:

@Repository
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
    @PostConstruct //在构造方法之后执行,替换 init-method
    public void init() {
        System.out.println("init ...");
    }

[外链图片转存中…(img-DnCByHpv-1715839111477)]
[外链图片转存中…(img-hlIm7dhW-1715839111477)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值