Spring-IOC注解编程
这里的注解是最初级的一些注解,掌握了之后再学习其它的注解
注解扫描
<?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 https://www.springframework.org/schema/context/spring-context.xsd"> <!--此标签表示开启注解扫描,即扫描对应包及其子包的注解--> <context:component-scan base-package="com.ty"></context:component-scan></beans>
除了上述方式还可以指定过滤规则来进行注解扫描
<context:component-scan base-package="com.ty"><!--排除过滤,排除包中的某些类 type="":指定过滤规则 annotation:按照注解进行排除,标注了指定注解的组件不要,expression表示要过滤的注解 assignable:指定排除某个具体的类,按照类排除,expression表示不注册的具体类名 aspectj:后面讲aop的时候说明要使用的aspectj表达式,不用 custom:定义一个typeFilter,自己写代码决定哪些类被过滤掉,不用 regex:使用正则表达式过滤,不用 --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>
<!--包含过滤,指定包中的类需要先配置use-default-filters属性,让默认扫描方式失效,默认是扫描全部剩下的过滤属性跟排除过滤相同--><context:component-scan base-package="com.ty" use-default-filters="false"> <context:include-filter type="aspectj" expression="com.ty.other.*"/></context:component-scan>
创建对象
@Component
此注解就是原配置方式中的<bean>标签,即:<bean id="user" class="com.ty.bean.User">
注解中组件的id默认是类名首字母小写,class就是底层通过反射获取User类信息;通过@Component分别又衍生出三个注解
注解 | 含义、说明 |
---|---|
@Component | 没有明显含义 |
@Controller | 控制器,推荐给controller层添加此注解 |
@Service | 业务逻辑,推荐给业务逻辑层添加此注解 |
@Repository | 数据库管理,推荐给数据访问层添加此注解 |
这4个注解产生的效果方式是相同的,只是为了方便阅读,提高可读性
@Componentpublic class User { private String username; private String password; /*省略构造,getter/setter和toString方法 */}
@Scope
设置bean对象的作用域,就是bean标签中的scope属性
@Lazy
延迟创建单实例对象,就是bean标签中的lazy="false"属性
@PostConstruct
@PreDestroy
这两个注解表示bean对象的对象的生命周期,就是bean标签中的init-method和destroy-method属性
@PostConstructpublic void init() { System.out.println("init");}@PreDestroypublic void destroy() { System.out.println("destroy");}
依赖注入
@Autowired
@Repositorypublic class UserDaoImpl implements UserDao { @Override public void findUser() { System.out.println("查询用户!"); }}
@Servicepublic class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public void login() { userDao.findUser(); }}
注意:此注解默认是按照类型进行自动装配(就是注入)
1、如果只找到一个,则直接进行赋值,
2、如果没有找到,则直接抛出异常,
3、如果找到多个,那么会按照变量名作为id继续匹配,
匹配上直接进行装配
如果匹配不上则直接报异常
@Servicepublic class UserServiceImpl implements UserService { @Autowired private UserDao userDao2; @Override public void login() { userDao2.findUser(); }}//UserServiceImpl2继承UserServiceImpl类@Servicepublic class UserServiceImpl2 extends UserServiceImpl { @Autowired private UserDao userDao; @Override public void login() { System.out.println("UserServiceImpl2"); userDao.findUser(); }}
@Controllerpublic class UserController { @Autowired private UserService userServiceImpl; public void test() { userServiceImpl.login(); }}
方法上也可以有@Autowired注解
@Autowiredpublic void setUserService(UserService userServiceImpl) { this.userService = userServiceImpl;}
@Qualifier
此注解配套@Autowired使用,用来指定id的名字,让其按照名字装配;按照名字找到了就进行装配,否则就报错
@Controllerpublic class UserController { @Autowired @Qualifier("userServiceImpl") private UserService userService; public void test() { userService.login(); }}
@Autowired注解可以用在方法上,@Qualifier只可以用在参数列表中
@Autowiredpublic void test(@Qualifier("userServiceImpl2") UserService userService) { System.out.println("此方法被调用:" + userService);}
ps:方法上有@AutoWired注解时:bean创建时会自动调用,这个方法的每个参数都会自动注入
@Qualifier注解作用在参数上时,指定属性的id名字
@Resource
@Resource注解的作用和@Autowired的作用相同,而且@Resource(name="") = @Autowired+@Resource
public class UserController { @Resource(name = "userServiceImpl") private UserService userService;}等同于:public class UserController { @Autowired @Qualifier("userServiceImpl") private UserService userService;}
两者的功能相同,但还是有区别的:
@Autowired注解是Spring提供的,而@Resource是JavaEE规范提供的
@Autowired注解默认按照类型装配,而@Resource注解默认是按照名字装配
@Value
属性赋值,这种方式不能用在静态变量上,而且不能注入集合类型
#先定义一个properties属性文件,并设置要注入属性的值username=jackpassword=root
<!--把刚刚定义好的properties属性文件加载到配置文件中--><context:property-placeholder location="classpath:bean.properties"></context:property-placeholder>或者在类上添加@PropertySource("bean.properties")注解
//在属性上加 @Value("${key}") 注解@Value("${username}")private String username;@Value("${password}")private String password;
最后再看一下泛型依赖
泛型依赖
public class Student {}public class Teacher {}
public interface BaseDao<T> {void save();}//StudentDao.java@Repositorypublic class StudentDao implements BaseDao<Student> { @Override public void save() { System.out.println("保存学生!"); }}//TeacherDao.java@Repositorypublic class TeacherDao implements BaseDao<Teacher> { @Override public void save() { System.out.println("保存老师!"); }}
public class BaseService<T> { @Autowired private BaseDao<T> baseDao; public void save(){ baseDao.save(); }}//StudentService.java@Servicepublic class StudentService extends BaseService<Student> {}//TeacherService.java@Servicepublic class TeacherService extends BaseService<Teacher> {}
//测试ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");StudentService studentService = context.getBean("studentService", StudentService.class);TeacherService teacherService = context.getBean("teacherService", TeacherService.class);studentService.save();teacherService.save();