注解开发@Component@Autowired使用@Resource@POSTConstructor@preDestroybean作用范围@Scope依赖注入@Value第三方bean管理@Bean使用
注解开发
我们以前是需要用bean.xml,在其中我们需要写配置bean,那么现在我们改用注解了,想要添加那个bean对象,就在那个类上加上注解。
直接在当前类上或者方法上、或者属性上,添加注解就可以直接使用,就可以完成类的管理和属性注入。
xml优点:逻辑清晰(各有优点和缺点,视情况选择开发方式)
使用Spring需要导包
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.0.RELEASE</version> </dependency>
@Component
修饰一个类,将这个类交给Spring管理
@Component的衍生注解(衍生的注解跟@Component注解作用相同)
@Service 修饰service层的类 @Controller 修饰web层的类 @Repository 修饰dao层的类
这里只是部分注解(并没有完全的替代xml文件)
@Component("bookDao")//注解功能 可以取代xml中的<bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"></bean>语句功能 public class BookDaoImpl implements BookDao{ public void save() { System.out.println("book dao save ..."); } } //但在xml中需要标注,下面语句 <context:component-scan base-package="org.example.dao.impl">
@Repository("bookDao")
在Dao层注解
对整个xml的注解
@Configuration//核心结构,设置当前类为配置类 @ComponentScan("org.example")//用于设定扫描路径,此注解只能添加一次,多个数据用数组格式 /*这个可以扫描多个目录,更加具体(细) * @ComponentScan({"org.example.service","org.example.dao"}) * */ public class SpringConfig { }
对应的java调用
//从读配置文件,转变成读配置类 ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); //貌似只有AnnotationConfigApplicationContext 对象才能调用close() 方法
@Autowired使用
@Autowired是将@Repository修饰的类注入到当前修饰的对象上
实例
//BookDaoImpl.java @Repository("bookDao")//写参数的原因是为了调用时使用@Qualifier来指明具体的类对象 public class BookDaoImpl implements BookDao { // @Value("KekeFen") @Value("${name}") private String name; public void save() { System.out.println("Book Dao save..."+name); } }
//BookDaoImpl2.java @Repository("bookDao2") public class BookDaoImpl2 implements BookDao { public void save() { System.out.println("Book Dao save2222..."); } }
//BookServiceImpl.java 要调用别的类的类 @Service //修饰不一样,service就应该用Service来修饰 public class BookServiceImpl implements BookService { @Autowired //Autowired修饰的BookDao,注入的一定是BookDao对象的实例,也就是BookDaoImpl对象 @Qualifier("bookDao2")//强制按名字来完成属性的注入 private BookDao bookDao;//上面的@Autowired会将名为bookDao2的类赋给这里的bookDao //以便下面在Service层来调用Dao层的对象 public void save(){ System.out.println("Book Service save..."); bookDao.save(); } }
@Resource
和@Autowired功能很类似可以简化代码
使用@AutoWired和@Resource注解都可以不用写set方法,因为Spring通过反射暴力对Filed进行赋值
当然也可以标注在属性的setter方法上,也是可以注入的,如果标在属性上那么就是通过set赋值。
BookServiceImpl.java 要调用别的类的类 @Service public class BookServiceImpl implements BookService { @Resource(name = "bookDao2") private BookDao bookDao;//上面的@Autowired会将名为bookDao2的类赋给这里的bookDao //以便下面在Service层来调用Dao层的对象 public void save(){ System.out.println("Book Service save..."); bookDao.save(); } }
@Resource和@Autowired的不同点
1.基因不同:@Autowired是由org.springframework.factory.annotation.Autowired提供,也就是由Spring提供。@Resources是由javax.annotation.Resource提供,即J2EE提供。需要JDK1.6及以上
2.注入方式:@Autowired默认按byType注入,也可以byName;@Resource默认按byName自动注入,也提供byType注入
@Autowired private BWM bwm; //(默认的查找名称为bwm) @Resource private Benz benz; //(默认的查找名称为benz)如果name和id是自己定义的
@Autowired 配合 @Qualifier("name") 使用
@Resource(name="name")
总结:
@Autowired
按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果查询的结果不止一个,那么@Autowired会根据名称来查找。如果我们想使用按名称装配,也可以结合@Qualifier注解一起使用。
@Resource
有两个中重要的属性:name和type。name属性指定byName,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。需要注意的是,@Resource如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。
@POSTConstructor
初始化方法 相当于init-method,在工厂获得Spring管理的对象,自动执行其对应的初始化方法
@preDestroy
销毁方法 相当于destroy-method=“destroy”,在工厂获得Spring管理的对象,自动执行其对应的销毁方法
@Service("customerService")//<bean id="" class="" init-method="init" destroy-method="destroy"> public class CustomerService { @PostConstruct //相当于init-method,在工厂获得Spring管理的对象,自动执行其对应的初始化方法,修饰的是下面的方法 public void init() { System.out.println("CustomerService被初始化了。。。。。"); } public void save() { System.out.println("Service的save的方法执行。。。。。"); } @PreDestroy //相当于destroy-method="destroy",在工厂获得Spring管理的对象,自动执行其对应的销毁方法 public void destroy() { System.out.println("CustomerService被销毁了。。。。。"); } }
bean作用范围
@Scope
singleton 默认单例
prototype 多例
@Repository // 相当于<bean></bean>语句的作用 @Scope//单列(默认的) public class BookDaoImpl implements BookDao{ public void save(){ System.out.println("Book dao save..."); } @PostConstruct//初始化操作 public void init(){ System.out.println("init..."); } @PreDestroy//执行close()摧毁时的操作 public void destroy(){ System.out.println("destroy..."); } }
java类调用
public class App{ public static void main(String[] args){ AnnotationConfigApplicationContext xtc = new AnnotationConfigApplicationContext(SpringConfig.class); BookDao bookDao1 = ctx.getBean(BookDao.class); BookDao bookDao2 = ctx.getBean(BookDao.class); System.out.println(bookDao1);//打印的两个是同一个东西 System.out.println(bookDao2); ctx.close(); } }
Component必须和componentscan一起存在吗?
可以单独存在,Component可以单独注解的
依赖注入
注解的依赖注入
对于实现类(...Impl.java)
添加@Repository("具体名称-自定义")
对于实现类需要添加别人的对象时
类声明@Service
对象声明
@Autowired
@Qualifiter("具体名称")
@Value
简单类型
@Repository("bookDao2") public class BookDaoImpl implements BookDao { @Value("KekeFen")//添加@Value能设置属性值 private String name;
普通类型传参
新建jdbc.properties
name=KekefenProperties
SpringConfig.java中 配置文件信息
@PropertySource({"jdbc.properties",}) // 添加配置文件
@Configuration @ComponentScan("org.example") @PropertySource({"jdbc.properties",}) // 添加配置文件 public class SpringConfig { }
实现类中引用
@Value("${name}")//使用${} 符号来引用 private String name;
第三方bean管理
第三方类新建类JdbcConfig.java
public class JdbcConfig { @Bean//表示下面方法产生的对象,将交给Spring管理 public DataSource dataSource(){ DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/string_db"); ds.setUsername("root"); ds.setPassword("root"); return ds; }
SpringConfig.java
@Import({JdbcConfig.class})//引用新建的JdbcConfig类对象到容器中去
@Configuration @ComponentScan("org.example") @PropertySource({"jdbc.properties",})//大括号 引用多个对象 @Import({JdbcConfig.class})//引用新建的JdbcConfig类对象到容器中去 public class SpringConfig { }
调用的代码
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); DataSource dataSource = ctx.getBean(DataSource.class); System.out.println(dataSource); System.out.println( "结束" );
@Bean使用
第三方管理的主要东西
Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。 产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。@Bean明确地指示了一种方法,什么方法呢?产生一个bean的方法,并且交给Spring容器管理;从这我们就明白了为啥@Bean是放在方法的注释上了,因为它很明确地告诉被注释的方法,你给我产生一个Bean,然后交给Spring容器,剩下的你就别管了。记住,@Bean就放在方法上,就是让方法去产生一个Bean,然后交给Spring容器。
自动装配引用类型