详细的描述了Spring中的注解开发。
注解开发定义Bean
步骤:
1.使用@Component定义Bean
以下两种方式都可以定义Bean
@Component(“Bean的名称”)
@Component
其中第一种方式可以使用 ctx.getBean(“名称”)
其中第二种方式只能使用 ctx.getBean(“类型.class”) 因为没有指定名称
2.核心配置文件中通过组件扫描加载Bean
<context:component-scan base-package="wang"/>
|
注意:
Spring提供@Component注解的三个衍生注解
@controller:用于表现层bean定义
@service:用于业务层bean定义.
@Repository:用于数据层bean定义
样例代码:
impl实现类:
package wang.dao.impl;
import org.springframework.stereotype.Component; import wang.dao.Dao;
@Component("dao") public class DaoImpl implements Dao { @Override public void save() { System.out.println("Dao save() ..."); } }
|
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:component-scan base-package="wang"/>
</beans>
|
主函数:
package wang;
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import wang.dao.Dao;
public class App4 { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml.bak"); Dao dao = (Dao) ctx.getBean("dao"); dao.save(); } }
|
运行结果:
纯注解开发模式
Spring3.0升级了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道
如何取消配置文件呢,使用一个配置类来代替配置文件
package wang.config;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;
@Configuration @ComponentScan("wang") public class SpringConfig {
}
|
注意:
@ComponentScan(“wang”) 代替了中间的组件扫描器的功能
@Configuration代替了 xml 配置文件中的其他配置,如下图:
注意:ComponentScan({“wang.xxx01”, “wang.xxx02”}) 可以扫描多个类
主函数中需要改变一行代码:
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
|
改为:
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
|
此时删除xml配置文件运行结果相同:
Bean的管理
Bean的作用范围
@Scope(“prototype”)即可更改
Bean的生命周期
如下代码:
实现类:
package wang.dao.impl;
import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import wang.dao.Dao;
import javax.annotation.PostConstruct; import javax.annotation.PreDestroy;
@Component @Scope("singleton") public class DaoImpl implements Dao { @Override public void save() { System.out.println("Dao save() ..."); }
@PostConstruct public void init() { System.out.println("init() ... "); }
@PreDestroy public void destroy() { System.out.println("destroy() ..."); } }
|
主函数:
package wang;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import wang.config.SpringConfig; import wang.dao.Dao;
public class AppForAnnotation { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); Dao dao1 = ctx.getBean(Dao.class); Dao dao2 = ctx.getBean(Dao.class); System.out.println(dao1); System.out.println(dao2); ctx.close(); } }
|
注意关闭容器或关闭钩子可以看到销毁操作
运行结果如下:
注解开发依赖注入
@AutoWired —> 实现了引用类型的注入
注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法
注意:自动装配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法,请提供唯一的构造方法
样例代码如下:
package wang.service.impl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import wang.dao.Dao; import wang.service.Service;
@Service public class ServiceImpl implements Service { @Autowired @Qualifier("dao") private Dao dao;
@Override public void save() { System.out.println("Service save() ..."); dao.save(); } }
|
@Value(“变量值”) —> 实现了简单类型的注入
简单的样例代码如下:
@Service public class ServiceImpl implements Service { @Value("wang") private string name;
@Override public void save() { System.out.println("Service save() ..." + name); } }
|
那么为什么不直接将name定义为“wang”呢?为什么还要多此一举呢?
因为可以通过@Value注入properties
在配置类中加入如下注解
@PropertySource({“xxx.properties”,“xxx.properties”}) 注意:不允许使用通配符
此时可以通过@Value(“${ 属性名 }”) 访问properties中的属性
注解开发管理第三方Bean
@Bean 表示当前方法的返回值是一个Bean
@Configuration public class SpringConfig { @Bean public Datasource dataSource() { DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName("com.mysq1.jdbc.Driver"); ds.setUr1("jdbc:mysql://localhost:3306/spring_db"); ds.setUsername("root"); ds.setPassword("1234"); return ds; } }
|
写好当前配置文件后,在独立的配置类中导入当前配置类
方法1.扫描式 @ComponentScan({“xxx.service”, “xxx.dao”, “xxx.config”}) 不推荐
方法2.导入式 @Import(xxxconfig.class) 推荐,更为清晰
注入普通类型:
@Value("com.mysql.jdbc.Driver") private string driver; @value("jdbc:mysq1://localhost:3306/spring_db") private string url; @Value("root") private string userName; @Value("1234") private string password;
|
使用@Value注入
注入引用类型
public Datasource dataSource() { DruidDataSource ds = new DruidDataSource(Dao dao); System.out.println(dao); }
|
直接在形参声明即可,自动注入
XML配置对比注解配置
功能 |
XML配置 |
注解配置 |
定义Bean |
bean标签 • id属性 • class属性 |
@Component • @Controller • @Service • @Repository<br>@ComponentScan |
设置依赖注入 |
setter注入(set方法) • 引用类型/简单类型 构造器注入(构造方法) • 引用类型/简单类型 自动装配 |
@AutoWired • @Qualifier<br>@Value |
配置第三方Bean |
bean标签 静态工厂、实例工厂、FactoryBean |
@Bean |
作用范围 |
• scope属性 |
@Scope |
生命周期 |
标椎接口 • init-method • destroy-method |
@PostConstructor<br>@PreDestroy |