Spring四个方面的功能:
Spring:解决企业级应用开发的复杂性而创造的。服务端的开发,测试性,松耦合
maven
控制反转,对一个对象的控制权的反转
将对象的创建、初始化、销毁交给容器管理,Bean注册到Spring容器中,使用时。其他对象需要使用Bean是,直接去Spring容器中要
进行bean注入,使用反射方法创建对象
xml中定义bean
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
构造方法注入
<bean class="org.javagirl.ioc.model.User" id="user">
<!-- 查找构造方法-->
<constructor-arg value="1" name="id"/>
<constructor-arg value="2" name="username"/>
<constructor-arg value="3" name="address"/>
</bean>
set方法注入
<bean class="org.javagirl.ioc.model.User" id="user2">
<property name="id" value="2"></property>
<property name="username" value="2"></property>
<property name="address" value="2"></property>
</bean>
p名称空间注入
<bean class="org.javagirl.ioc.model.User" id="user3" p:username="javagirl" p:id="3" p:address="java.com">
</bean>
工厂方法容器注入
静态工厂注入
实例工厂注入:获取两个实例,更加具体
<bean class="org.javagirl.ioc.model.User" id="user4">
<property name="id" value="2"></property>
<property name="username" value="2"></property>
<property name="address" value="2"></property>
<property name="cat" ref="cat"></property>
</bean>
<bean id="cat" class="org.javagirl.ioc.model.Cat">
<property name="name" value="xiaoxiao">
</property>
<property name="age" value="4"></property>
</bean>
<bean class="org.javagirl.ioc.model.User" id="user4">
<property name="id" value="2"></property>
<property name="username" value="2"></property>
<property name="address" value="2"></property>
<property name="cat" ref="cat"></property>
<property name="cats">
<array>
<ref bean="cat"/>
<bean class="org.javagirl.ioc.model.Cat" id="cat2">
<property name="name" value="xiaoxiao"></property>
<property name="age" value="4"></property>
</bean>
</array>
</property>
<property name="favorites">
<list>
<value>说的话</value>
<value>比如</value>
</list>
</property>
</bean>
<bean id="cat" class="org.javagirl.ioc.model.Cat">
<property name="name" value="xiaoxiao"></property>
<property name="age" value="4"></property>
</bean>
<bean class="org.javagirl.ioc.model.User" id="user4">
<property name="id" value="2"></property>
<property name="username" value="2"></property>
<property name="address" value="2"></property>
<property name="cat" ref="cat"></property>
<property name="cats">
<array>
<ref bean="cat"/>
<bean class="org.javagirl.ioc.model.Cat" id="cat2">
<property name="name" value="xiaoxiao"></property>
<property name="age" value="4"></property>
</bean>
</array>
</property>
<property name="favorites">
<list>
<value>说的话</value>
<value>比如</value>
</list>
</property>
<property name="details">
<map>
<entry key="gender" value="女"></entry>
<entry value="232" key="age"></entry>
</map>
</property>
<property name="info">
<props>
<prop key="phone">132333</prop>
</props>
</property>
</bean>
<bean id="cat" class="org.javagirl.ioc.model.Cat">
<property name="name" value="xiaoxiao"></property>
<property name="age" value="4"></property>
</bean>
springboot中使用java配置开发,不使用xml配置
//表示这是一个java配置类,类似于applicationContext.xml
@Configuration
public class JavaConfig {
@Bean
SayHello sayHello(){
return new SayHello();
}
}
public class JavaConfigTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
SayHello sayHello = ctx.getBean("sayHello", SayHello.class);
System.out.println(sayHello.sayHello("javagirl"));
}
}
包扫描
@Service作为一个标记
@Component 其它组件
@Controller
@Repository Dao层
定义Service @Service
Config配置文件中定义包扫描
@Configuration
@ComponentScan(basePackages = "org.javagirl.ioc.service")
获取对象并测试
Bean的名字是类名首字母小写,自定义在@service("名字")
扫描按照包的位置扫描可以定义过滤字段
定义Service
xml文件中定义component-scan
@Autowired
根据类型去查找,然后赋值,这个类型只可以有一个对象,否则就会报错
dao文件
@Repository
public class UserDao {
public String hello(){
return "hello";
}
}
@Service
public class UserService {
@Autowired
UserDao userDao;
@Resources
根据名称去查找,默认情况下,定义的变量名就是查找的名称。如果一个类存在多个实例,使用该注入方式进行注入。@Autowired需要和@Qualifier(指定变量名)配合使用
@Injected
较少使用
满足在某一个条件的情况下,生效的配置
@Conditional()
开发,生产,测试环境
Profile,底层为条件注解
@Profile
Main:
ctx.getEnvironment().setActiveProfiles("dev");
@Bean
@Profile("dev")
DataSource devDs(){
DataSource ds = new DataSource();
ds.setUrl("jdbc:mysql:///vhr");
ds.setPassword("root");
ds.setUsername("root");
return ds;
}
@Profile("pro")
@Bean
DataSource proDs(){
DataSource ds = new DataSource();
ds.setUrl("jdbc:mysql://172.0.0.1:3307/vhr");
ds.setPassword("root");
ds.setUsername("root");
return ds;
}
定义beans,进行配置
singleton 默认从spring容器中多次获取的是同一个Bean,单例
scope="protype" 表示获取多个实例
id和name都可以给Bean指定一个唯一标识符
name支持取多个名字
Java配置+XML配置
在Java配置中引入XML配置
@ImportResource("classpath:applicationContext.xml")
感知捕获,单纯的一个Bean是没有感知
Aware接口可以获取容器的详细信息
@Service
@PropertySource(value="javagirl.properties")
public class AwareService implements BeanNameAware, BeanFactoryAware, ResourceLoaderAware, EnvironmentAware {
private String beanName;
private Environment environment;
private ResourceLoader resourceLoader;
/**
* 获取工厂环境
* @param environment
*/
@Override
public void setEnvironment(Environment environment) {
this.environment=environment;
}
public void output() throws IOException {
System.out.println("beanName = " + beanName);
Resource resource = resourceLoader.getResource("javagirl.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream()));
String s = br.readLine();
System.out.println("s = " + s);
br.close();
String address = environment.getProperty("javagirl.address");
System.out.println("address = " + address);
}
/**
* 获取bean的生成工厂
* @param beanFactory
* @throws BeansException
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
}
/**
* 获取bean的名字
* @param s
*/
@Override
public void setBeanName(String s) {
this.beanName=s;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader=resourceLoader;
}
}
Aop,面向切面编程,对面向对象思想的补充
在不改变源码的情况下,动态的增强方法的功能
日志,事务,数据库操作等
基于Java动态代理的实现
实现:
方法增强
public class CalculatorProxy {
public static Object getInstance(MyCalculatorImpl myCalculator){
return Proxy.newProxyInstance(CalculatorProxy.class.getClassLoader(), myCalculator.getClass().getInterfaces(), new InvocationHandler() {
/**
*
* @param proxy 代理对象
* @param method 代理方法
* @param args 方法参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName()+":方法开始执行");
Object invoke = method.invoke(myCalculator, args);
System.out.println(method.getName()+":方法执行结束");
return invoke;
}
});
}
}
@Component
@Aspect
public class LogAspect {
/**
* 前置通知
* @param joinPoint
*/
@Before("@annotation(Action)")
public void before(JoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
System.out.println("add方法开始执行了");
}
}
/**
* 后置通知,在目标方法之后执行
* @param joinPoint
*/
@After("@annotation(Action)")
public void after(JoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法执行结束了");
}
/**
* 异常通知:当目标方法抛出宜昌市,该方法会被触发
* @param joinPoint
* @param e 异常参数,和方法参数名一一对应,注意异常类型,Exception
*/
@AfterThrowing(value= "@annotation(Action)",throwing = "e")
public void afterThrowing(JoinPoint joinPoint,Exception e){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法异常通知"+e.getMessage());
}
/**
* 返回通知,参数类型匹配时有返回通知,Object可以匹配所有类型
* @param joinPoint
* @param r 返回的参数名称,和方法的参数名一一对应
*/
@AfterReturning(value = "@annotation(Action)",returning = "r")
public void returning(JoinPoint joinPoint,Object r){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法返回通知"+r);
}
@Around("@annotation(Action)")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
//类似于method.invoke方法,可以在这个方法的前后分别添加日志,相当于前置/后置通知
Object proceed = pjp.proceed();
return proceed;
}
通过方法定义切点
@Pointcut("@annotation(Action)")
public void pointcut(){
}
另一种方法
@Pointcut("execution(* aop.service.*.*(..))")
public void pointcut(){
}
JdbcTemplate时Spring利用Aop思想封装的Jdbc操作工具
配置jdbc
利用Aop思想,简化事务的配置,可以通过java配置也可以通过XML配置
@Transactional 注解
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。