Spring学习记录3
IOC基于注解
注解的作用
注解是java的特殊标记,其格式为@注解名称(属性名称=属性值,属性名称=属性值…)
注解可以作用在方方面面,如类上面,方法上面,变量(属性)上面
spring使用注解,简化xml配置
spring针对bean创建对象的注解
@Component
@Service
@Controller
@Repository
上面的四个注解功能是一样的,都可以创建对象
基于注解方式实现对象的创建
1.引入spring-aop jar包
2.开启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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启组件扫描
base-package写入需要扫描的包名
如果需要扫描多个包
1.中间加,隔开
2.写扫描包的上层包
-->
<!-- <context:component-scan base-package="Furrain.zhujie,Furrain.bean"></context:component-scan>-->
<context:component-scan base-package="Furrain"></context:component-scan>
</beans>
3.创建类,在类上添加注解
package Furrain.zhujie.Service;
import org.springframework.stereotype.Component;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName UserService
* @createDate 2020/12/13 18:55
* @see Furrain.zhujie.Service
*/
//在注解中,value的值可以不写
//如果不写,默认是首字母小写的类名
// UserService --- userService
@Component(value = "userService") //等同于<bean id="userService" class="....."></bean>
public class UserService {
public void add() {
System.out.println("zhujie user service...");
}
}
测试
@Test
public void testService() {
ApplicationContext context = new ClassPathXmlApplicationContext("zhujie/bean1.xml");
UserService us = context.getBean("userService",UserService.class);
us.add();
}
配置组件扫描的细节
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启组件扫描
base-package写入需要扫描的包名
如果需要扫描多个包
1.中间加,隔开
2.写扫描包的上层包
-->
<!-- <context:component-scan base-package="Furrain.zhujie,Furrain.bean"></context:component-scan>-->
<context:component-scan base-package="Furrain"></context:component-scan>
<!-- 不使用默认的扫描规则
context:include-filter 设置扫描哪些内容 type 类型 如 annotation注解 expression 具体哪个注解
-->
<!-- <context:component-scan base-package="Furrain" use-default-filters="false">-->
<!-- <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
<!-- </context:component-scan>-->
<!--扫描所有文件,但是不包含xxxx-->
<context:component-scan base-package="Furrain">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
</context:component-scan>
</beans>
注解 注入属性
有哪些注解注入属性
对象类型
@AutoWired --根据属性类型自动装配
@Qualifier --根据属性名臣注入
@Resource --可以类型也可以名称
普通类型
@Value
AutoWired操作
1.给两个类都添加创建对象的注解
2.注入对象属性变量(注解注入 与xml区别,不需要写setter方法,注解帮我们做了)
package Furrain.zhujie.Dao;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName UserDao
* @createDate 2020/12/13 19:34
* @see Furrain.zhujie.Dao
*/
public interface UserDao {
public void add();
}
package Furrain.zhujie.Dao;
import org.springframework.stereotype.Service;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName UserDaoImpl
* @createDate 2020/12/13 19:35
* @see Furrain.zhujie.Dao
*/
@Service
public class UserDaoImpl implements UserDao{
@Override
public void add() {
System.out.println("dao impl add...");
}
}
package Furrain.zhujie.Service;
import Furrain.zhujie.Dao.UserDao;
import Furrain.zhujie.Dao.UserDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName UserService
* @createDate 2020/12/13 18:55
* @see Furrain.zhujie.Service
*/
//在注解中,value的值可以不写
//如果不写,默认是首字母小写的类名
// UserService --- userService
@Component(value = "userService") //等同于<bean id="userService" class="....."></bean>
public class UserService {
//不需要setter方法
// 添加注入属性注解
// AutoWired 根据类型注入,这里用了impl,假设用dao,如果dao有多个实现类,我觉得会报错吧
@Autowired
private UserDaoImpl daoImpl;
public void add() {
System.out.println("zhujie user service...");
daoImpl.add();
}
}
Qualifier 操作
这个注解的使用,需要和上面一起使用 别问,问就是规定
package Furrain.zhujie.Dao;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName UserDao
* @createDate 2020/12/13 19:34
* @see Furrain.zhujie.Dao
*/
public interface UserDao {
public void add();
}
package Furrain.zhujie.Dao;
import org.springframework.stereotype.Service;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName UserDaoImpl
* @createDate 2020/12/13 19:35
* @see Furrain.zhujie.Dao
*/
@Service(value = "impppp")
public class UserDaoImpl implements UserDao{
@Override
public void add() {
System.out.println("dao impl add...");
}
}
package Furrain.zhujie.Service;
import Furrain.zhujie.Dao.UserDao;
import Furrain.zhujie.Dao.UserDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName UserService
* @createDate 2020/12/13 18:55
* @see Furrain.zhujie.Service
*/
//在注解中,value的值可以不写
//如果不写,默认是首字母小写的类名
// UserService --- userService
@Component(value = "userService") //等同于<bean id="userService" class="....."></bean>
public class UserService {
//不需要setter方法
// 添加注入属性注解
// AutoWired 根据类型注入,如果dao有多个实现类,他就没法确认用哪个,需要名称指定
@Autowired
@Qualifier(value = "impppp")
private UserDao dao;
public void add() {
System.out.println("zhujie user service...");
dao.add();
}
}
Resource操作
需要avax.annotation包的依赖
<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.1</version> </dependency>
其他没什么好说的与上面两个类似
@Resource就是按类型注入
@Resource(name = “impppp”)就是按名称注入
Value操作
用于普通类型的
@Value(value=“xxxx”)
思考
那么List 数组等类型该怎么用注解注入呢。。。
我研究了半天不知道,或许可以这样?
@Resource(name = "petlist")
private List<String> pets;
@Bean(name = "petlist")
public List<String> list(){
ArrayList<String> list=new ArrayList<String>();
list.add("大黄");
list.add("小黑");
list.add("小花");
list.add("小白");
return list;
}
如果类型是自定义类呢
package Furrain.zhujie.Service;
import Furrain.zhujie.Dao.UserDao;
import Furrain.zhujie.Dao.UserDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName UserService
* @createDate 2020/12/13 18:55
* @see Furrain.zhujie.Service
*/
//在注解中,value的值可以不写
//如果不写,默认是首字母小写的类名
// UserService --- userService
@Component(value = "userService") //等同于<bean id="userService" class="....."></bean>
public class UserService {
//不需要setter方法
// 添加注入属性注解
// AutoWired 根据类型注入,如果dao有多个实现类,他就没法确认用哪个,需要名称指定
@Resource(name = "impppp")
private UserDao dao;
@Resource(name = "petlist")
private List<String> pets;
@Bean(name = "petlist")
public List<String> list(){
ArrayList<String> list=new ArrayList<String>();
list.add("大黄");
list.add("小黑");
list.add("小花");
list.add("小白");
return list;
}
@Autowired
private List<UserDao> daoList;
@Autowired
private Map<String,UserDao> mapDao;
public void add() {
System.out.println(name);
System.out.println(pets);
System.out.println("zhujie user service...");
dao.add();
System.out.println(daoList);
System.out.println(mapDao);
}
@Value("xxxx")
private String name;
}
实现了两个userDao接口
package Furrain.zhujie.Dao;
import org.springframework.stereotype.Service;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName UserDaoImpl
* @createDate 2020/12/13 19:35
* @see Furrain.zhujie.Dao
*/
@Service(value = "impppp")
public class UserDaoImpl implements UserDao{
@Override
public void add() {
System.out.println("dao impl add...");
}
@Override
public String toString() {
return "dao impl add...";
}
}
package Furrain.zhujie.Dao;
import org.springframework.stereotype.Component;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName Imp1
* @createDate 2020/12/13 20:27
* @see Furrain.zhujie.Dao
*/
@Component
public class Imp1 implements UserDao{
@Override
public void add() {
System.out.println("impl1 addxxxx");
}
@Override
public String toString() {
return "impl1 addxxxx";
}
}
打印测试结果是
xxxx
[大黄, 小黑, 小花, 小白]
zhujie user service...
dao impl add...
[impl1 addxxxx, dao impl add...]
{imp1=impl1 addxxxx, impppp=dao impl add...}
由此可见对于自定义类型autowired后会自动帮我们填进去,map的key值是类的名称(@Compont(vaule=“xxx”))
完全注解开发
上面我们虽然都用到了注解,但是还是在xml中写了一行开启组件扫描
那么怎么连xml都不需要呢
1实现配置类
package Furrain.zhujie.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* <Description>
*
* @author Furrain
* @version 1.0
* @ClassName springconfig
* @createDate 2020/12/13 20:41
* @see Furrain.zhujie.config
*/
@Configuration //注解的作用是表明配置类,代替配置文件
@ComponentScan(basePackages = {"Furrain"})
public class springconfig {
}
测试
@Test
public void testServiceNoXml() {
// ApplicationContext context = new AnnotationConfigApplicationContext("Furrain");
ApplicationContext context = new AnnotationConfigApplicationContext(springconfig.class);
UserService us = context.getBean("userService",UserService.class);
us.add();
}
可以看到上面还注释了一行,可以直接在里面写扫描包,那么连配置类也不需要了
听说这就是springboot的模式呢,后面再看…