目录
运行run2()会报错,因为现在是SpringConfig的配置类
②SpringConfig配置类中引入SpringConfig2配置类
IOC注解的依赖没有变,和配置文件方式的一样
一、半注解
半注解是注解+配置文件
1.接口和实现类
接口
public interface UserService {
public void hello();
}
实现类
/** * <bean id="us" class="cn.tx.demo2.UserServiceImpl" /> */
// 组件,作用:把当前类使用IOC容器进行管理,如果没有指定名称,默认使用类名,首字母是小写。userServiceImpl。或者自己指定名称
@Component(value = "us")
public class UserServiceImpl implements UserService {
public void hello(){
System.out.println("Hello IOC注解...");
}
}
2.配置文件
重点:开启扫描
<?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">
<!--配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring_db"></property>
<property name="username" value="root"></property>
<property name="password" value="2020"></property>
</bean>
<!--管理bean-->
<bean id="accountService" class="com.test.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<bean id="accountDao" class="com.test.dao.impl.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启注解扫描-->
<context:component-scan base-package="com.test"></context:component-scan>
</beans>
3.测试类
import com.test.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo2 {
@Test
public void run1(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("application.xml");
UserService userService=(UserService) applicationContext.getBean("us");
userService.hello();
}
}
4.运行结果
5.常用注解
(1)bean管理类常用的4个注解
@Component 普通的类
@Controller 表现层
@Service 业务层
@Repository 持久层
(2)依赖注入常用的注解
@Value 用于注入普通类型(String,int,double等类型)
@Autowired 默认按类型进行自动装配(引用类型)
@Qualifier 和@Autowired一起使用,强制使用名称注入
@Resource Java提供的注解,也被支持。使用name属性,按名称注入
(3)对象生命周期注解
@Scope 生命周期注解,取值singleton(默认值,单例)和prototype(多例)
@PostConstruct 相当于init-method
@PreDestroy 相当于destroy-method
二、纯注解
没有配置文件了,换成了配置类
纯注解的方式是微服务架构开发的主要方式,纯注解的目的是替换掉所有的配置文件。但是需要编写配置类。
1.实体类
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Order {
@Value("北京")
private String address;
@Override
public String toString() {
return "Order{" +
"address='" + address + '\'' +
'}';
}
}
2.配置类
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;
/*
* Spring的配置类,替换掉application.xml
* */
@Configurable //声明当前是配置类,这个注解是spring框架的,能用是因为pom.xml导入了spring的依赖
@ComponentScan(value = "...pojo") //扫描指定的包结构
public class SpringConfig {
}
3.测试类
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Demo {
@Test
public void run1(){
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);
Order order=(Order) applicationContext.getBean("order");
System.out.println(order);
}
}
4.运行结果
5.多配置类加载方式
现在有两个类,都交给spring管理,一个类是上面的Order类(在pojo包下),下面还有一个Order01类(在pojo2包下)
Order01类
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "order01")
public class Order01 {
@Value("上海")
private String address;
@Value("李四")
private String name;
@Override
public String toString() {
return "Order01{" +
"address='" + address + '\'' +
", name='" + name + '\'' +
'}';
}
}
配置类SpringConfig
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import javax.sql.DataSource;
/*
* Spring的配置类,替换掉application.xml
* */
@Configurable //声明当前是配置类
@ComponentScan(value = "pojo") //扫描指定的包结构
public class SpringConfig {
}
}
配置类SpringConfig2
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration //声明当前是配置类
@ComponentScan(value = "pojo2")
public class SpringConfig2 {
}
测试类
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Demo {
@Test
public void run1(){
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);
Order order=(Order) applicationContext.getBean("order");
System.out.println(order);
}
@Test
public void run2(){
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);
Order01 order01=(Order01) applicationContext.getBean("order01");
System.out.println(order01);
}
}
运行run2()会报错,因为现在是SpringConfig的配置类
三种办法解决这个错误
①配置类改成SpringConfig2
@Test
public void run2(){
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig2.class);
Order01 order01=(Order01) applicationContext.getBean("order01");
System.out.println(order01);
}
此时就会运行成功
②SpringConfig配置类中引入SpringConfig2配置类
@Configurable //声明当前是配置类
@ComponentScan(value = "com.qcby.pojo") //扫描指定的包结构
@Import(value = {SpringConfig2.class}) //引入新的配置类
public class SpringConfig {
}
此时也是可以运行成功的
③run2()方法中,ApplicationContext applicationContext=new AnnotationConfigApplicationContext();括号里面可以传两个参数
@Test
public void run2(){
//ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class,SpringConfig2.class);
Order01 order01=(Order01) applicationContext.getBean("order01");
System.out.println(order01);
}
此时也会运行成功
6.常用注解
(1)@Configuration
声明是配置类
(2)@ComponentScan
扫描具体包结构的
(3)@Import注解
Spring的配置文件可以分成多个配置的,也就是可以编写多个配置类。这个注解用于导入其他配置类(下面这个是例子,第二个配置类导入到第一个配置类里用到了这个注解)
第一个配置类
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
/*
* Spring的配置类,替换掉application.xml
* */
@Configurable //声明当前是配置类
@ComponentScan(value = "pojo") //扫描指定的包结构
@Import(value = {SpringConfig2.class}) //引入新的配置类
public class SpringConfig {
}
第二个配置类
import org.springframework.context.annotation.Configuration;
/*
* 新的配置类
* */
@Configuration //声明当前是配置类
public class SpringConfig2 {
}
(4)@Bean注解
只能写在方法上,表明使用此方法创建一个对象,对象创建完成保存到IOC容器中(下面这个是例子)
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import javax.sql.DataSource;
/*
* Spring的配置类,替换掉application.xml
* */
@Configurable //声明当前是配置类
@ComponentScan(value = "pojo") //扫描指定的包结构
@Import(value = {SpringConfig2.class}) //引入新的配置类
public class SpringConfig {
/**
*
* 创建连接池对象,返回对象,把该方法创建后的对象存入到连接池中,使用@Bean注解解决
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql:///spring_db" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
*
* @return
*/
@Bean(name = "dataSource")
public DataSource createDataSource(){
DruidDataSource dataSource=new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_db");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
}